<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2+%D0%90%D1%80%D1%82%D0%B5%D0%BC</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2+%D0%90%D1%80%D1%82%D0%B5%D0%BC"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC"/>
	<updated>2026-10-22T21:29:46Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=20059</id>
		<title>Обсуждение участника:Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=20059"/>
		<updated>2016-12-05T09:43:46Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Замечания второго рецензента */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB]] ==&lt;br /&gt;
=== Замечания второго рецензента ===&lt;br /&gt;
* В тексте нет ссылок на источники&lt;br /&gt;
** Добавил. [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 12:43, 5 декабря 2016 (MSK)&lt;br /&gt;
* Сам список оформлен плохо - только гиперссылки. Кроме ссылок нужны названия источников&lt;br /&gt;
** Теперь оформлен хорошо. [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 12:43, 5 декабря 2016 (MSK)&lt;br /&gt;
* п 1.1 - поясните, что такое концепт&lt;br /&gt;
** Пояснил, теперь это есть в статье. [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 12:43, 5 декабря 2016 (MSK)&lt;br /&gt;
* п 1.2 - что такое A и B?&lt;br /&gt;
** B -- воообще не нашёл в п.1.2, про A написано в самом начале. На всякий случай добавил побольше появнений к буквам по всему тексту. [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 12:43, 5 декабря 2016 (MSK)&lt;br /&gt;
* п 1.3 - список как-то неудачен - соседние пункты - это куски фраз&lt;br /&gt;
** Переделал в текст, добавил немного пояснений. Теперь должно читаться проще. [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 12:43, 5 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* В разделе 1.5 кроме псевдокода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7, не является информационным графом (ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
** Замечание не исправлено. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 13:17, 30 ноября 2016 (MSK)&lt;br /&gt;
*** Исправил [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 02:17, 1 декабря 2016 (MSK)&lt;br /&gt;
* В разделе 1.9 должны быть оценки объёмов входных и выходных данных. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 должна быть оценка вычислительной мощности алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
** Замечание не исправлено. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 13:17, 30 ноября 2016 (MSK)&lt;br /&gt;
*** Понятие компилятора и его опций неприменимо для языка Python. Версия интерпретатора была указана (Python 3.5), дополнительных библиотек не использовалось, способ запуска также указан (модель процессора, количество потоков). [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 02:17, 1 декабря 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведена использованная в экспериментах реализация алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Из графиков в разделе 2.4 следует сделать выводы о масштабируемости реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Рисунки в статье не пронумерованы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В список литературы следует включить ссылки по описываемому алгоритму. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20058</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20058"/>
		<updated>2016-12-05T09:39:44Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039;&amp;lt;ref name=&amp;quot;wiki&amp;quot; /&amp;gt;&amp;lt;ref name=&amp;quot;paper&amp;quot; /&amp;gt; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&amp;lt;ref name=&amp;quot;habr&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&amp;lt;ref name=&amp;quot;shit&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref name=&amp;quot;gh_cf&amp;quot; /&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;https://docs.python.org/3.5/library/multiprocessing.html — библиотека multiprocessing для распараллеливания программ на Python&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;https://en.wikipedia.org/wiki/Cobweb_(clustering) — описание алгоритма на Википедии (Eng)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;habr&amp;quot;&amp;gt;https://habrahabr.ru/post/164417/ — сравнение алгоритма COBWEB с другими алгоритмами кластеризации&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;shit&amp;quot;&amp;gt;http://bourabai.ru/tpoi/analysis6.htm — подробное описание алгоритма COBWEB&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;paper&amp;quot;&amp;gt;http://www.cl.cam.ac.uk/~av308/cobweb.pdf — статья, в которой алгоритм COBWEB был впервые представлем&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20057</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20057"/>
		<updated>2016-12-05T09:38:35Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&amp;lt;ref name=&amp;quot;habr&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&amp;lt;ref name=&amp;quot;shit&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref name=&amp;quot;gh_cf&amp;quot; /&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;https://docs.python.org/3.5/library/multiprocessing.html — библиотека multiprocessing для распараллеливания программ на Python&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;https://en.wikipedia.org/wiki/Cobweb_(clustering) — описание алгоритма на Википедии (Eng)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;habr&amp;quot;&amp;gt;https://habrahabr.ru/post/164417/ — сравнение алгоритма COBWEB с другими алгоритмами кластеризации&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;shit&amp;quot;&amp;gt;http://bourabai.ru/tpoi/analysis6.htm — подробное описание алгоритма COBWEB&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;paper&amp;quot;&amp;gt;http://www.cl.cam.ac.uk/~av308/cobweb.pdf — статья, в которой алгоритм COBWEB был впервые представлем&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20056</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20056"/>
		<updated>2016-12-05T09:38:16Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&amp;lt;ref name=&amp;quot;habr&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref name=&amp;quot;gh_cf&amp;quot; /&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;https://docs.python.org/3.5/library/multiprocessing.html — библиотека multiprocessing для распараллеливания программ на Python&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;https://en.wikipedia.org/wiki/Cobweb_(clustering) — описание алгоритма на Википедии (Eng)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;habr&amp;quot;&amp;gt;https://habrahabr.ru/post/164417/ — сравнение алгоритма COBWEB с другими алгоритмами кластеризации&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;shit&amp;quot;&amp;gt;http://bourabai.ru/tpoi/analysis6.htm — подробное описание алгоритма COBWEB&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;paper&amp;quot;&amp;gt;http://www.cl.cam.ac.uk/~av308/cobweb.pdf — статья, в которой алгоритм COBWEB был впервые представлем&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20055</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20055"/>
		<updated>2016-12-05T09:37:48Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref name=&amp;quot;gh_cf&amp;quot; /&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;https://docs.python.org/3.5/library/multiprocessing.html — библиотека multiprocessing для распараллеливания программ на Python&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;https://en.wikipedia.org/wiki/Cobweb_(clustering) — описание алгоритма на Википедии (Eng)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;habr&amp;quot;&amp;gt;https://habrahabr.ru/post/164417/ — сравнение алгоритма COBWEB с другими алгоритмами кластеризации&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;shit&amp;quot;&amp;gt;http://bourabai.ru/tpoi/analysis6.htm — подробное описание алгоритма COBWEB&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;paper&amp;quot;&amp;gt;http://www.cl.cam.ac.uk/~av308/cobweb.pdf — статья, в которой алгоритм COBWEB был впервые представлем&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20054</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20054"/>
		<updated>2016-12-05T09:37:00Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref name=&amp;quot;gh_cf&amp;quot; /&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;https://docs.python.org/3.5/library/multiprocessing.html — библиотека multiprocessing для распараллеливания программ на Python&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Cobweb_(clustering) — описание алгоритма на Википедии (Eng)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;https://habrahabr.ru/post/164417/ — сравнение алгоритма COBWEB с другими алгоритмами кластеризации&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://bourabai.ru/tpoi/analysis6.htm — подробное описание алгоритма COBWEB&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://www.cl.cam.ac.uk/~av308/cobweb.pdf — статья, в которой алгоритм COBWEB был впервые представлем&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20053</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20053"/>
		<updated>2016-12-05T09:36:40Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref name=&amp;quot;gh_cf&amp;quot; /&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;https://docs.python.org/3.5/library/multiprocessing.html — библиотека multiprocessing для распараллеливания программ на Python&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Cobweb_(clustering) — описание алгоритма на Википедии (Eng)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;https://habrahabr.ru/post/164417/ — сравнение алгоритма COBWEB с другими алгоритмами кластеризации&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://bourabai.ru/tpoi/analysis6.htm — подробное описание алгоритма COBWEB&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://www.cl.cam.ac.uk/~av308/cobweb.pdf — статья, в которой алгоритм COBWEB был впервые представлем&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20052</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20052"/>
		<updated>2016-12-05T09:32:02Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref name=&amp;quot;gh_cf&amp;quot; /&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;https://docs.python.org/3.5/library/multiprocessing.html — библиотека multiprocessing для распараллеливания программ на Python&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20051</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20051"/>
		<updated>2016-12-05T09:31:01Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot; — библиотека, содержащая реализацию алгоритма COBWEB на языке Python&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/ — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20050</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20050"/>
		<updated>2016-12-05T09:30:34Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot; — библиотека, содержащая реализацию алгоритма COBWEB на языке Python&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref name=&amp;quot;gh_cf&amp;quot;&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека, содержащая реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;http://www.cs.waikato.ac.nz/~ml/weka — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot;&amp;lt;ref&amp;gt;&amp;lt;/ref&amp;gt; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20047</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20047"/>
		<updated>2016-12-05T09:27:57Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot; — библиотека, содержащая реализацию алгоритма COBWEB на языке Python&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;https://github.com/cmaclell/concept_formation/ — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20046</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20046"/>
		<updated>2016-12-05T09:27:16Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot; — библиотека, содержащая реализацию алгоритма COBWEB на языке Python&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20045</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20045"/>
		<updated>2016-12-05T09:25:00Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма (всего &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20044</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20044"/>
		<updated>2016-12-05T09:24:17Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt;). На каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20043</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20043"/>
		<updated>2016-12-05T09:23:22Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_k|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20042</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20042"/>
		<updated>2016-12-05T09:22:57Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A_j = u_{ij}|C_k) P(C_K|A_j = u_{ij}) P(A_j = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20041</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=20041"/>
		<updated>2016-12-05T09:21:39Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт (концепт — описание группы объектов через определенный набор пар аттрибут-значение) и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=20040</id>
		<title>Обсуждение участника:Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=20040"/>
		<updated>2016-12-05T09:17:37Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB]] ==&lt;br /&gt;
=== Замечания второго рецензента ===&lt;br /&gt;
* В тексте нет ссылок на источники&lt;br /&gt;
* Сам список оформлен плохо - только гиперссылки. Кроме ссылок нужны названия источников&lt;br /&gt;
* п 1.1 - поясните, что такое концепт&lt;br /&gt;
* п 1.2 - что такое A и B?&lt;br /&gt;
* п 1.3 - список как-то неудачен - соседние пункты - это куски фраз&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* В разделе 1.5 кроме псевдокода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7, не является информационным графом (ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
** Замечание не исправлено. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 13:17, 30 ноября 2016 (MSK)&lt;br /&gt;
*** Исправил [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 02:17, 1 декабря 2016 (MSK)&lt;br /&gt;
* В разделе 1.9 должны быть оценки объёмов входных и выходных данных. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 должна быть оценка вычислительной мощности алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
** Замечание не исправлено. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 13:17, 30 ноября 2016 (MSK)&lt;br /&gt;
*** Понятие компилятора и его опций неприменимо для языка Python. Версия интерпретатора была указана (Python 3.5), дополнительных библиотек не использовалось, способ запуска также указан (модель процессора, количество потоков). [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 02:17, 1 декабря 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведена использованная в экспериментах реализация алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Из графиков в разделе 2.4 следует сделать выводы о масштабируемости реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Рисунки в статье не пронумерованы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В список литературы следует включить ссылки по описываемому алгоритму. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19778</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19778"/>
		<updated>2016-11-30T23:20:55Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ assignment }}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19777</id>
		<title>Обсуждение участника:Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19777"/>
		<updated>2016-11-30T23:19:55Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Статья Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB]] ==&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* В разделе 1.5 кроме псевдокода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7, не является информационным графом (ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
** Замечание не исправлено. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 13:17, 30 ноября 2016 (MSK)&lt;br /&gt;
*** Исправил [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 02:17, 1 декабря 2016 (MSK)&lt;br /&gt;
* В разделе 1.9 должны быть оценки объёмов входных и выходных данных. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 должна быть оценка вычислительной мощности алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
** Замечание не исправлено. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 13:17, 30 ноября 2016 (MSK)&lt;br /&gt;
*** Понятие компилятора и его опций неприменимо для языка Python. Версия интерпретатора была указана (Python 3.5), дополнительных библиотек не использовалось, способ запуска также указан (модель процессора, количество потоков). [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 02:17, 1 декабря 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведена использованная в экспериментах реализация алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Из графиков в разделе 2.4 следует сделать выводы о масштабируемости реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Рисунки в статье не пронумерованы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В список литературы следует включить ссылки по описываемому алгоритму. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Re: Замечания по тексту ===&lt;br /&gt;
Все исправил. [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 04:57, 30 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19776</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19776"/>
		<updated>2016-11-30T23:14:27Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_0&amp;lt;/math&amp;gt; — корневой узел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{11}, N_{12}, ..., N_{1L}&amp;lt;/math&amp;gt; — узлы первого уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{21}, N_{22}, ..., N_{2L}&amp;lt;/math&amp;gt; — узлы второго уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N_{B1}, N_{B2}, ..., N_{BL}&amp;lt;/math&amp;gt; — узлы последнего уровня&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C_1, C_2, ..., C_L&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;
* При неограниченном ресурсе параллелизма, вычисление функции полезности может быть произведено за &amp;lt;math&amp;gt;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19775</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19775"/>
		<updated>2016-11-30T23:12:03Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow-2.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:Cobweb-flow-2.png&amp;diff=19774</id>
		<title>Файл:Cobweb-flow-2.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:Cobweb-flow-2.png&amp;diff=19774"/>
		<updated>2016-11-30T23:11:48Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19566</id>
		<title>Обсуждение участника:Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19566"/>
		<updated>2016-11-30T01:57:53Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Re: Замечания по тексту */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB]] ==&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* В разделе 1.5 кроме псевдокода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7, не является информационным графом (ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.9 должны быть оценки объёмов входных и выходных данных. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 должна быть оценка вычислительной мощности алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* В разделе 2.4 не приведена использованная в экспериментах реализация алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Из графиков в разделе 2.4 следует сделать выводы о масштабируемости реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Рисунки в статье не пронумерованы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В список литературы следует включить ссылки по описываемому алгоритму. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Re: Замечания по тексту ===&lt;br /&gt;
Все исправил. [[Участник:Казаков Артем|Казаков Артем]] ([[Обсуждение участника:Казаков Артем|обсуждение]]) 04:57, 30 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19565</id>
		<title>Обсуждение участника:Казаков Артем</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:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19565"/>
		<updated>2016-11-30T01:56:19Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Статья Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB]] ==&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* В разделе 1.5 кроме псевдокода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7, не является информационным графом (ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.9 должны быть оценки объёмов входных и выходных данных. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 должна быть оценка вычислительной мощности алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* В разделе 2.4 не приведена использованная в экспериментах реализация алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Из графиков в разделе 2.4 следует сделать выводы о масштабируемости реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK) &lt;br /&gt;
* Рисунки в статье не пронумерованы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
* В список литературы следует включить ссылки по описываемому алгоритму. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:46, 28 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Re: Замечания по тексту ===&lt;br /&gt;
Все исправил.&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19437</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19437"/>
		<updated>2016-11-28T23:56:54Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ assignment }}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 624)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19433</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19433"/>
		<updated>2016-11-28T21:55:38Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ assignment }}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19432</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19432"/>
		<updated>2016-11-28T21:53:45Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
* https://en.wikipedia.org/wiki/Cobweb_(clustering)&lt;br /&gt;
* https://habrahabr.ru/post/164417/&lt;br /&gt;
* http://bourabai.ru/tpoi/analysis6.htm&lt;br /&gt;
* http://www.cl.cam.ac.uk/~av308/cobweb.pdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19431</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19431"/>
		<updated>2016-11-28T21:51:14Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19430</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19430"/>
		<updated>2016-11-28T21:51:04Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
1. asdf&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19429</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19429"/>
		<updated>2016-11-28T21:50:05Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;http://java-ml.sourceforge.net/&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19428</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19428"/>
		<updated>2016-11-28T21:49:28Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ Concept Formation]&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation/&amp;quot; — библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python&amp;lt;/ref&amp;gt; библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka]&amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka Weka&amp;quot; — библиотека и инструмент для анализа данных на языке Java&amp;lt;/ref&amp;gt; библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] &amp;lt;ref&amp;gt;&amp;quot;http://www.cs.waikato.ac.nz/~ml/weka Weka&amp;quot; — библиотека машинного обучения на языке Java&amp;lt;/ref&amp;gt; библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19427</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19427"/>
		<updated>2016-11-28T21:46:58Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[file:Cobweb-flow.png|thumb|center|750px|Рис. 1 Информационный граф алгоритма COBWEB]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19426</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19426"/>
		<updated>2016-11-28T21:45:35Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python из библиотки Concept Formation&amp;lt;ref&amp;gt;&amp;quot;https://github.com/cmaclell/concept_formation&amp;quot;&amp;lt;/ref&amp;gt; и распараллелена с использованием средств Python multiprocessing&amp;lt;ref&amp;gt;&amp;quot;https://docs.python.org/3.5/library/multiprocessing.html&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
* Версия Python: 3.5&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных Библиоткеи Concept Formation (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Рис. 2 Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Рис. 3 Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Таким образом можно сделать вывод о том, что данная реализация обладает слабой масштабируемостью. Во многом это связано с высокими накладными расходами на параллелизм в среде исполнения Python.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19424</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19424"/>
		<updated>2016-11-28T21:27:57Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
Оценка вычислительной мощности алгоритма составляет &amp;lt;math&amp;gt;O(N * B * V * (A + logN))&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;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19423</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19423"/>
		<updated>2016-11-28T21:21:15Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
На вход алгоритм принимает множество объектов, характеризуемых набором свойств. В свою очередь, каждое свойство может принимать какое-либо значение из множества допустимых значений. Оценка объема входных данных составляет &amp;lt;math&amp;gt;O(N*A)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результатом работы алгоритма является построенное дерево классификации, листья которого представляют собой различные классы объектов и содержат сами объекты принадлежащие данному классу. Оценка объема выходных данных составляет &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19422</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19422"/>
		<updated>2016-11-28T21:20:23Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число объектов для классификации&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:Cobweb-flow.png&amp;diff=19421</id>
		<title>Файл:Cobweb-flow.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:Cobweb-flow.png&amp;diff=19421"/>
		<updated>2016-11-28T21:18:11Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: Казаков Артем загрузил новую версию Файл:Cobweb-flow.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19420</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19420"/>
		<updated>2016-11-28T21:14:59Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Алгоритм повторяется для каждого нового объекта. В данном алгоритме происходит спуск по дереву и на каждом шаге спуска выбирается одно из действий описанных в п. 1.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19271</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19271"/>
		<updated>2016-11-26T23:36:50Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;O(N*logN*log(BAV))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19270</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19270"/>
		<updated>2016-11-26T23:35:17Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19269</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19269"/>
		<updated>2016-11-26T23:35:06Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19268</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19268"/>
		<updated>2016-11-26T23:34:08Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19267</id>
		<title>Участник:Казаков Артем</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC&amp;diff=19267"/>
		<updated>2016-11-26T23:33:50Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: Новая страница: «-»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19266</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19266"/>
		<updated>2016-11-26T23:33:25Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков_Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19265</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19265"/>
		<updated>2016-11-26T23:33:08Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор статьи: [[Участник: Казаков Артем|Артем Казаков]] (группа 620)&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19264</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19264"/>
		<updated>2016-11-26T23:31:56Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6&lt;br /&gt;
&lt;br /&gt;
Данные выбирались из стандартной библиотеки тестовых данных тестируемого модуля (mushrooms).&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|640px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|640px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:Cobwebeff.png&amp;diff=19263</id>
		<title>Файл:Cobwebeff.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:Cobwebeff.png&amp;diff=19263"/>
		<updated>2016-11-26T23:29:31Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: Казаков Артем загрузил новую версию Файл:Cobwebeff.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</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:Cobwebtime.png&amp;diff=19262</id>
		<title>Файл:Cobwebtime.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:Cobwebtime.png&amp;diff=19262"/>
		<updated>2016-11-26T23:28:12Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: Казаков Артем загрузил новую версию Файл:Cobwebtime.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19248</id>
		<title>Участник:Казаков Артем/Алгоритм концептуальной кластеризации COBWEB</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9A%D0%B0%D0%B7%D0%B0%D0%BA%D0%BE%D0%B2_%D0%90%D1%80%D1%82%D0%B5%D0%BC/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BE%D0%BD%D1%86%D0%B5%D0%BF%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_COBWEB&amp;diff=19248"/>
		<updated>2016-11-26T18:58:07Z</updated>

		<summary type="html">&lt;p&gt;Казаков Артем: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм концептуальной кластеризации COBWEB &lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N*logN*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt;N*logN*log(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; — классический метод инкрементальной концептуальной кластеризации. Он создаёт иерархическую кластеризацию в виде дерева классификации: каждый узел этого дерева ссылается на концепт и содержит вероятностное описание этого концепта, которое включает в себя вероятность принадлежности концепта к данному узлу.&lt;br /&gt;
&lt;br /&gt;
Узлы, находящейся на определённом уровне дерева классификации, называют срезом. Алгоритм использует для построения дерева классификации эвристическую меру оценки, называемую полезностью категории — прирост ожидаемого числа корректных предположений о значениях атрибутов при знании об их принадлежности к определённой категории относительно ожидаемого числа корректных предположений о значениях атрибутов без этого знания. Чтобы встроить новый объект в дерево классификации, алгоритм &#039;&#039;&#039;COBWEB&#039;&#039;&#039; итеративно проходит всё дерево в поисках «лучшего» узла, к которому отнести этот объект. Выбор узла осуществляется на основе помещения объекта в каждый узел и вычисления полезности категории получившегося среза. Также вычисляется полезность категории для случая, когда объект относится к вновь создаваемому узлу. В итоге объект относится к тому узлу, для которого полезность категории наибольшая.&lt;br /&gt;
&lt;br /&gt;
Однако &#039;&#039;&#039;COBWEB&#039;&#039;&#039; имеет ряд ограничений. Во-первых, он предполагает, что распределения вероятностей значений различных атрибутов статистически независимы друг от друга. Однако это предположение не всегда верно, потому как часто между значениями атрибутов существует корреляция. Во-вторых, вероятностное представление кластеров делает очень сложным их обновление, особенно в том случае, когда атрибуты имеют большое число возможных значений. Это вызвано тем, что сложность алгоритма зависит не только от количества атрибутов, но и от количества их возможных значений.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Обозначим:&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ A_{1}, A_{2}, ... \}&amp;lt;/math&amp;gt; — множество свойств кластеризуемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_{1j}, u_{2j}, ... \}&amp;lt;/math&amp;gt; —  возможнные значения свойства &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ C_{1}, C_{2}, ... \}&amp;lt;/math&amp;gt; — множество категорий&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; — это условная вероятность, с которой свойство &amp;lt;math&amp;gt;A_{j}&amp;lt;/math&amp;gt;, принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, если объект относится к категории &amp;lt;math&amp;gt;C_{k}&amp;lt;/math&amp;gt;. Для каждой категории в иерархии определены вероятности вхождения всех значений каждого свойства. При предъявлении нового экземпляра система &#039;&#039;&#039;COBWEB&#039;&#039;&#039; оценивает качество отнесения этого примера к существующей категории и модификации иерархии категорий в соответствии с новым представителем. Критерием оценки качества классификации является полезность категории (&#039;&#039;category utility&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Критерий полезности категории максимизирует вероятность того, что два объекта, отнесенные к одной категории, имеют одинаковые значения свойств и значения свойств для объектов из различных категорий отличаются. Полезность категории определяется формулой&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;CU = \sum_{k} \sum_{i} \sum_{j} P(A = u_{ij}|C_k) P(C_K|A = u_{ij}) P(A = u_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значения суммируются по всем категориям &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;, всем свойствам &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; и всем значениям свойств &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Значение &amp;lt;math&amp;gt;P(A_j = u_{ij} | C_k)&amp;lt;/math&amp;gt; называется предсказуемостью (predictability). Это вероятность того, что объект, для которого свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;, относится к категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt;. Чем выше это значение, тем вероятнее, что свойства двух объектов, отнесенных к одной категории, имеют одинаковые значения. Величина &amp;lt;math&amp;gt;P(C_k | A = u_{ij})&amp;lt;/math&amp;gt; называется предиктивностью (predictiveness). Это вероятность того, что для объектов из категории &amp;lt;math&amp;gt;C_k&amp;lt;/math&amp;gt; свойство &amp;lt;math&amp;gt;A_j&amp;lt;/math&amp;gt; принимает значение &amp;lt;math&amp;gt;u_{ij}&amp;lt;/math&amp;gt;. Чем больше эта величина, тем менее вероятно, что для объектов, не относящихся к данной категории, это свойство будет принимать указанное значение. Значение &amp;lt;math&amp;gt;P(A = u_{ij})&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;N&amp;lt;/math&amp;gt; шагов) &lt;br /&gt;
* производится спуск по дереву (&amp;lt;math&amp;gt;O(log_{B}N)&amp;lt;/math&amp;gt; итераций)&lt;br /&gt;
* на каждой итерации спуска производится &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt; вычислений полезности категории &amp;lt;math&amp;gt;CU&amp;lt;/math&amp;gt;, &lt;br /&gt;
* вычисление каждой из которых имеет сложность &amp;lt;math&amp;gt;O(BAV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножив сложности выше получам сложность из п. 1.6., что подтверждает, что основная часть вычислительных операций приходится именно на вычисление полезностей категорий.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В алгоритме &#039;&#039;&#039;COBWEB&#039;&#039;&#039; реализован метод поиска экстремума в пространстве возможных кластеров с использованием критерия полезности категорий для оценки и выбора возможных способов категоризации.&lt;br /&gt;
&lt;br /&gt;
* Сначала вводится единственная категория, свойства которой совпадают со свойствами первого экземпляра. &lt;br /&gt;
* Для каждого последующего экземпляра алгоритм начинает свою работу с корневой категории и движется далее по дереву. &lt;br /&gt;
* На каждом уровне выполняется оценка эффективности категоризации на основе полезности категории. При этом оцениваются результаты следующих операций:&lt;br /&gt;
** Отнесение экземпляра к наилучшей из существующих категорий.&lt;br /&gt;
** Добавление новой категории, содержащей единственный экземпляр.&lt;br /&gt;
** Слияние двух существующих категорий в одну новую с добавлением в нее этого экземпляра.&lt;br /&gt;
** Разбиение существующей категории на две и отнесение экземпляра к лучшей из вновь созданных категорий.&lt;br /&gt;
* Для слияния двух узлов создается новый узел, для которого существующие узлы становятся дочерними. На основе значений вероятностей дочерних узлов вычисляются вероятности для нового узла. При разбиении один узел заменяется двумя дочерними.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;pre&amp;gt;cobweb(Node, Instance)&lt;br /&gt;
 Begin&lt;br /&gt;
  if узел Node - это лист, then&lt;br /&gt;
    begin&lt;br /&gt;
     создать два дочерних узла L1 и L2 для узла Node;&lt;br /&gt;
     задать для узла L1 те же вероятности, что и для узла Node;&lt;br /&gt;
     инициализировать вероятности для узла L2 соответствующими значениями объекта Instance;&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node ;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    begin&lt;br /&gt;
     добавить Instance к Node, обновив вероятности для узла Node;&lt;br /&gt;
     для каждого дочернего узла С узла Node вычислить полезность категории при отнесении экземпляра Instance к категории С;&lt;br /&gt;
     пусть S1 - значение полезности для наилучшей классификации C1;&lt;br /&gt;
     пусть S2 - значение для второй наилучшей классификации C2;&lt;br /&gt;
     пусть S3 - значение полезности для отнесения экземпляра к новой категории;&lt;br /&gt;
     пусть S4 - значение для слияния C1 и C2 в одну категорию;&lt;br /&gt;
     пусть S5 - значение для разделения C1 (замены дочерними категориями);&lt;br /&gt;
    end&lt;br /&gt;
   if S1 - максимальное значение CU, then&lt;br /&gt;
     cobweb(C1, Instance) %отнести экземпляр к C1&lt;br /&gt;
   else&lt;br /&gt;
     if S3 - максимальное значение CU, then&lt;br /&gt;
       инициализировать вероятности для новой категории Cm значениями Instance &lt;br /&gt;
     else &lt;br /&gt;
       if S4 - максимальное значение CU, then &lt;br /&gt;
         begin&lt;br /&gt;
           пусть Cm - результат слияния C1 и C2; &lt;br /&gt;
           cobweb(Cm, Instance);&lt;br /&gt;
         end &lt;br /&gt;
       else&lt;br /&gt;
         if S5 - максимальное значение CU, then &lt;br /&gt;
           begin &lt;br /&gt;
             разделить C1; % Cm - новая категория&lt;br /&gt;
             cobweb(Cm, Instance)&lt;br /&gt;
           end;&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма равна &amp;lt;math&amp;gt;O(N*log_{B}N*B^{2}AV)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — среднее число потомков узлов в дереве классификации &lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число уже классифицированных объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; — числа свойств у классифицируемых объектов&lt;br /&gt;
* &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; — среднее число значений, которые могут принимать свойства&lt;br /&gt;
&lt;br /&gt;
Обоснование сложности приводится в п. 1.3.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Cobweb-flow.png|750px]]&lt;br /&gt;
&lt;br /&gt;
Для выполнения каждой итерации алгоритма (добавления очередного элемента в дерево классификации) необходимо иметь доступ по всему текущему состоянию дерева классификации. &lt;br /&gt;
&lt;br /&gt;
Однако, внутри шага алгоритма зависимость по данным отсутствует. Возможно произвести расчет функции полезности для каждого кластера независимо и в конце сравнить их значения.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма ==&lt;br /&gt;
&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;O(log(BAV))&amp;lt;/math&amp;gt; через независимое вычисление каждой её составной части (за &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;) и последующую их параллельную редукцию за &amp;lt;math&amp;gt;O(log(q))&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q=BAV&amp;lt;/math&amp;gt; — количество составных частей функции полезности.&lt;br /&gt;
* Вычисление совокупности функций полезности (которых &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;) также может быть распараллелено c последующей параллельной редукцией за &amp;lt;math&amp;gt;O(log(B))&amp;lt;/math&amp;gt; и итоговой параллельной сложностью &amp;lt;math&amp;gt;O(log(BAV)+log(B))=log(BAV))&amp;lt;/math&amp;gt; (при неограниченном ресурсе параллелизма).&lt;br /&gt;
* Продвижение объектов по дереву может не может быть распараллелено, поскольку входные данные для каждой очередной итерации зависят от результата выполнения предыдущей. Всего за время работы алгоритма выполняется &amp;lt;math&amp;gt;O(N*logN)&amp;lt;/math&amp;gt; операций продвижения по дереву.&lt;br /&gt;
&lt;br /&gt;
Таким образом, итоговая параллельная сложность алгоритма равна &amp;lt;math&amp;gt;N*logN*log(BAV)&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;
Этот алгоритм достаточно эффективен и выполняет кластеризацию на разумное число классов. Поскольку в нем используется вероятностное представление принадлежности, получаемые категории являются гибкими и робастными. Кроме того, в нем проявляется эффект категорий базового уровня, поддерживается прототипирование и учитывается степень принадлежности. Он основан не на классической логике, а, подобно методам теории нечетких множеств, учитывает &amp;quot;неопределенность&amp;quot; категоризации как необходимый компонент обучения и рассуждений в гибкой и интеллектуальной манере.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== [[Локальность данных и вычислений]] ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма COBWEB проводилось на компьютере с процессором Intel(R) Core(TM) i7-5960X @ 4.30GHz, который поддерживает до 12ти потоков при наличии 6 физических ядер. Была взята реализация алгоритма COBWEB на Python и распараллелена с использованием средств Python multiprocessing.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным количеством объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, а также с различным числом процессоров. Фиксировались время работы и количество произведенных итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
* Количество объектов для кластеризации &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000&lt;br /&gt;
* Количество процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12&lt;br /&gt;
&lt;br /&gt;
Размер дополнительных входных параметов алгоритма определялся следующим образом:&lt;br /&gt;
* Количество свойств у классифицируемых объектов &amp;lt;math&amp;gt;A = 5&amp;lt;/math&amp;gt;&lt;br /&gt;
* Количество значений, которые могут принимать свойства &amp;lt;math&amp;gt;V = 10&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Входные данные генереривались перед запуском алгоритма с использованием детерменированного генератора псевдослучайных чисел.&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента и полученным результатам [[Глоссарий#Производительность|производительность]] и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Perf = \frac{N_{op}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{op}&amp;lt;/math&amp;gt; &amp;amp;mdash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Perf_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;Perf_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; Core i7&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5960&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/82930/Intel-Core-i7-5960X-Processor-Extreme-Edition-20M-Cache-up-to-3_50-GHz&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации COBWEB от числа векторов для кластеризации (&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены ниже.&lt;br /&gt;
&lt;br /&gt;
[[file:Cobwebtime.png|thumb|center|800px|Время работы алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
[[file:Cobwebeff.png|thumb|center|800px|Эффективность алгоритма COBWEB в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Существуют следующие реализации алгоритма COBWEB:&lt;br /&gt;
* [https://github.com/cmaclell/concept_formation/ concept_formation] библиотека реализации алгоритмов COBWEB и COBWEB/3 для языка Python.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://java-ml.sourceforge.net/ Java-ML] библиотека машинного обучения на языке Java.&lt;br /&gt;
&lt;br /&gt;
Так как существуют алгоритмы кластеризации, обладающие лучшими свойствами, алгоритм COBWEB практически не применяется и параллельных реализаций этого алгоритма нет.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Казаков Артем</name></author>
	</entry>
</feed>