0 added
24 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Одна из самых популярных практических задач в современном программировании - это<strong>поиск ближайших соседей</strong>. Например, поиск ближайших соседей встречается в медицине. Так строятся прогнозные модели заболеваемости, в которых оцениваются контакты в ближайшем окружении заболевшего:</p>
1
<p>Одна из самых популярных практических задач в современном программировании - это<strong>поиск ближайших соседей</strong>. Например, поиск ближайших соседей встречается в медицине. Так строятся прогнозные модели заболеваемости, в которых оцениваются контакты в ближайшем окружении заболевшего:</p>
2
<p>На рисунке выше вы можете увидеть координатную плоскость, на которой расположены:</p>
2
<p>На рисунке выше вы можете увидеть координатную плоскость, на которой расположены:</p>
3
<ul><li>"Заболевшие" красные точки</li>
3
<ul><li>"Заболевшие" красные точки</li>
4
<li>"Здоровые" синие точки</li>
4
<li>"Здоровые" синие точки</li>
5
<li>"Опасные зоны" - розовые окружности вокруг красных точек</li>
5
<li>"Опасные зоны" - розовые окружности вокруг красных точек</li>
6
</ul><p>Синяя точка подвергается риску заболеть, если она входит в опасную зону - располагается слишком близко к красной точке. Другими словами, чтобы синяя точка не заболела, расстояние между ней и красной точкой должно быть выше<strong>порогового значения</strong>.</p>
6
</ul><p>Синяя точка подвергается риску заболеть, если она входит в опасную зону - располагается слишком близко к красной точке. Другими словами, чтобы синяя точка не заболела, расстояние между ней и красной точкой должно быть выше<strong>порогового значения</strong>.</p>
7
<p>В этом примере задача сводится к поиску синих точек с высоким риском заболеть. Один из способов решения такой задачи - это кластеризация на основе методов машинного обучения. Но есть и альтернатива - это<strong>KD-деревья</strong>, о которых мы и поговорим в этом уроке.</p>
7
<p>В этом примере задача сводится к поиску синих точек с высоким риском заболеть. Один из способов решения такой задачи - это кластеризация на основе методов машинного обучения. Но есть и альтернатива - это<strong>KD-деревья</strong>, о которых мы и поговорим в этом уроке.</p>
8
<h2>Что такое KD-деревья</h2>
8
<h2>Что такое KD-деревья</h2>
9
<p><strong>KD-деревья</strong>- это дерево, вершины которого представлены в форме точек в некоторой K-мерной системе координат. Еще их называют<em>K-dimensional trees</em>или "K-мерные деревья".</p>
9
<p><strong>KD-деревья</strong>- это дерево, вершины которого представлены в форме точек в некоторой K-мерной системе координат. Еще их называют<em>K-dimensional trees</em>или "K-мерные деревья".</p>
10
<p>В этом курсе мы рассматриваем только KD-деревья в двумерном пространстве. Но с его помощью можно вычислять ближайшего соседа и на более сложных системах координат. Например, так выглядит трехмерное дерево:</p>
10
<p>В этом курсе мы рассматриваем только KD-деревья в двумерном пространстве. Но с его помощью можно вычислять ближайшего соседа и на более сложных системах координат. Например, так выглядит трехмерное дерево:</p>
11
<p>Обратим внимание, что эффективность поиска ближайших соседей в KD-дереве снижается при больших значениях K.</p>
11
<p>Обратим внимание, что эффективность поиска ближайших соседей в KD-дереве снижается при больших значениях K.</p>
12
<p>В качестве правила обычно принимают, что число вершин в дереве должно быть намного больше значения 2^K. Если это правило не соблюдать, то алгоритм поиска на основе KD-дерева будет работать с почти той же скоростью, что и обычный последовательный поиск.</p>
12
<p>В качестве правила обычно принимают, что число вершин в дереве должно быть намного больше значения 2^K. Если это правило не соблюдать, то алгоритм поиска на основе KD-дерева будет работать с почти той же скоростью, что и обычный последовательный поиск.</p>
13
<h2>Как устроено KD-дерево</h2>
13
<h2>Как устроено KD-дерево</h2>
14
<p>Чтобы изучить строение KD-дерева, возьмем для примера 13 точек в двумерной системе координат:</p>
14
<p>Чтобы изучить строение KD-дерева, возьмем для примера 13 точек в двумерной системе координат:</p>
15
<p>Чтобы построить по ним дерево, мы будем руководствоваться следующим алгоритмом:</p>
15
<p>Чтобы построить по ним дерево, мы будем руководствоваться следующим алгоритмом:</p>
16
<ol><li>Выберем ось в наборе данных</li>
16
<ol><li>Выберем ось в наборе данных</li>
17
<li>Найдем на этой оси<strong>медианное значение числа точек</strong>. Для двумерного пространства это значит, что справа и слева от значения должно быть одинаковое число точек. Если у нас четное число точек, то можно левое подпространство сделать больше правого</li>
17
<li>Найдем на этой оси<strong>медианное значение числа точек</strong>. Для двумерного пространства это значит, что справа и слева от значения должно быть одинаковое число точек. Если у нас четное число точек, то можно левое подпространство сделать больше правого</li>
18
<li>Проведем линию, которая разделит пространство на две части</li>
18
<li>Проведем линию, которая разделит пространство на две части</li>
19
<li>Изменим ось и нарисуем свою медиану для каждого нового подпространства</li>
19
<li>Изменим ось и нарисуем свою медиану для каждого нового подпространства</li>
20
</ol><p>Пройдя эти четыре шага, мы выполним первое<strong>разделение</strong>дерева. Далее мы повторяем все шаги до тех пор, пока точек больше не останется.</p>
20
</ol><p>Пройдя эти четыре шага, мы выполним первое<strong>разделение</strong>дерева. Далее мы повторяем все шаги до тех пор, пока точек больше не останется.</p>
21
<p>Посмотрим, как разделение работает на нашем примере - двумерном KD-дереве с 13 точками:</p>
21
<p>Посмотрим, как разделение работает на нашем примере - двумерном KD-дереве с 13 точками:</p>
22
<p><strong>Этап 1</strong>. Разделим пространство на основании оси X:</p>
22
<p><strong>Этап 1</strong>. Разделим пространство на основании оси X:</p>
23
<p><strong>Этап 2</strong>. Выполним второе разделение на основании оси Y:</p>
23
<p><strong>Этап 2</strong>. Выполним второе разделение на основании оси Y:</p>
24
<p><strong>Этап 3</strong>. Продолжаем разделение, пока это возможно:</p>
24
<p><strong>Этап 3</strong>. Продолжаем разделение, пока это возможно:</p>
25
<p><strong>Этап 4</strong>. Строим итоговое дерево, исходя из разделения пространства:</p>
25
<p><strong>Этап 4</strong>. Строим итоговое дерево, исходя из разделения пространства:</p>
26
<p>На последнем рисунке видно, что получившееся дерево аналогично сбалансированному бинарному дереву. Разница только в том, что в качестве полезной нагрузки в KD-дереве хранится точка с координатами.</p>
26
<p>На последнем рисунке видно, что получившееся дерево аналогично сбалансированному бинарному дереву. Разница только в том, что в качестве полезной нагрузки в KD-дереве хранится точка с координатами.</p>
27
<p>В таком случае JavaScript-код узла будет выглядеть так:</p>
27
<p>В таком случае JavaScript-код узла будет выглядеть так:</p>
28
-
<p><strong>Javascript</strong></p>
29
-
<p><strong>Java</strong></p>
30
-
<p><strong>Python</strong></p>
31
-
<p><strong>PHP</strong></p>
32
<h2>Операции над KD-деревом</h2>
28
<h2>Операции над KD-деревом</h2>
33
<p>Основное отличие KD-дерева можно увидеть при работе с методом, который отвечает за построение дерева из массива точек:</p>
29
<p>Основное отличие KD-дерева можно увидеть при работе с методом, который отвечает за построение дерева из массива точек:</p>
34
-
<p><strong>Javascript</strong></p>
35
-
<p><strong>Java</strong></p>
36
-
<p><strong>Python</strong></p>
37
-
<p><strong>PHP</strong></p>
38
<p>Вызвать построение дерева можно при помощи следующего примера:</p>
30
<p>Вызвать построение дерева можно при помощи следующего примера:</p>
39
-
<p><strong>Javascript</strong></p>
40
-
<p><strong>Java</strong></p>
41
-
<p><strong>Python</strong></p>
42
-
<p><strong>PHP</strong></p>
43
<p>Структура KD-дерева не отличается от бинарного дерева. Поэтому методы удаления и вставки узлов работают так же, как в бинарном дереве:</p>
31
<p>Структура KD-дерева не отличается от бинарного дерева. Поэтому методы удаления и вставки узлов работают так же, как в бинарном дереве:</p>
44
-
<p><strong>Javascript</strong></p>
45
-
<p><strong>Java</strong></p>
46
-
<p><strong>Python</strong></p>
47
-
<p><strong>PHP</strong></p>
48
<p>Удаление:</p>
32
<p>Удаление:</p>
49
-
<p><strong>Javascript</strong></p>
50
-
<p><strong>Java</strong></p>
51
-
<p><strong>Python</strong></p>
52
-
<p><strong>PHP</strong></p>
53
<p>Еще одной отличительной особенностью KD-дерева считается реализация метода поиска ближайшего соседа:</p>
33
<p>Еще одной отличительной особенностью KD-дерева считается реализация метода поиска ближайшего соседа:</p>
54
-
<p><strong>Javascript</strong></p>
55
-
<p><strong>Java</strong></p>
56
-
<p><strong>Python</strong></p>
57
-
<p><strong>PHP</strong></p>
58
<p>Для определения расстояния между точками используется метрика, чаще всего евклидова. Она позволяет вычислить, насколько близко одна точка находится к другой, что является ключевым аспектом при поиске ближайших соседей.</p>
34
<p>Для определения расстояния между точками используется метрика, чаще всего евклидова. Она позволяет вычислить, насколько близко одна точка находится к другой, что является ключевым аспектом при поиске ближайших соседей.</p>
59
<h3>Процесс поиска ближайших соседей</h3>
35
<h3>Процесс поиска ближайших соседей</h3>
60
<ol><li><strong>Инициализация</strong>:<ul><li>Поиск начинается с корневого узла дерева и заданной точки, для которой необходимо найти ближайшие соседи.</li>
36
<ol><li><strong>Инициализация</strong>:<ul><li>Поиск начинается с корневого узла дерева и заданной точки, для которой необходимо найти ближайшие соседи.</li>
61
</ul></li>
37
</ul></li>
62
<li><strong>Рекурсивный поиск</strong>:<ul><li>На каждом уровне дерева происходит сравнение координат искомой точки с координатами узла. В зависимости от результата сравнения, поиск продолжается в одном из дочерних узлов (левом или правом).</li>
38
<li><strong>Рекурсивный поиск</strong>:<ul><li>На каждом уровне дерева происходит сравнение координат искомой точки с координатами узла. В зависимости от результата сравнения, поиск продолжается в одном из дочерних узлов (левом или правом).</li>
63
<li>Если текущий узел ближе к искомой точке, чем уже найденные соседи, он добавляется в список лучших соседей.</li>
39
<li>Если текущий узел ближе к искомой точке, чем уже найденные соседи, он добавляется в список лучших соседей.</li>
64
</ul></li>
40
</ul></li>
65
<li><strong>Обновление списка лучших соседей</strong>:<ul><li>Если количество найденных соседей меньше заданного максимума, или если текущий узел ближе, чем самый дальний из уже найденных, он добавляется в список.</li>
41
<li><strong>Обновление списка лучших соседей</strong>:<ul><li>Если количество найденных соседей меньше заданного максимума, или если текущий узел ближе, чем самый дальний из уже найденных, он добавляется в список.</li>
66
<li>Если список заполнен, удаляется самый дальний сосед, чтобы освободить место для нового.</li>
42
<li>Если список заполнен, удаляется самый дальний сосед, чтобы освободить место для нового.</li>
67
</ul></li>
43
</ul></li>
68
<li><strong>Проверка других поддеревьев</strong>:<ul><li>После проверки одного из дочерних узлов, если расстояние до текущего узла позволяет, происходит проверка другого дочернего узла. Это необходимо для того, чтобы убедиться, что не пропущены более близкие соседи.</li>
44
<li><strong>Проверка других поддеревьев</strong>:<ul><li>После проверки одного из дочерних узлов, если расстояние до текущего узла позволяет, происходит проверка другого дочернего узла. Это необходимо для того, чтобы убедиться, что не пропущены более близкие соседи.</li>
69
</ul></li>
45
</ul></li>
70
</ol><h2>Выводы</h2>
46
</ol><h2>Выводы</h2>
71
<p>В этом уроке мы познакомились с KD-деревьями, которые помогают организовать хранение пространственных данных. KD-деревья - это основная альтернатива методам машинного обучения при решении кластеризационных задач.</p>
47
<p>В этом уроке мы познакомились с KD-деревьями, которые помогают организовать хранение пространственных данных. KD-деревья - это основная альтернатива методам машинного обучения при решении кластеризационных задач.</p>
72
<p>Поиск ближайших соседей - это одна из популярных задач, стоящих перед программистами. Результаты ее решения нужны в медицине, геологии, картографии и прочих прикладных областях, связанных с кластеризацией пространственных объектов.</p>
48
<p>Поиск ближайших соседей - это одна из популярных задач, стоящих перед программистами. Результаты ее решения нужны в медицине, геологии, картографии и прочих прикладных областях, связанных с кластеризацией пространственных объектов.</p>