Выпуклая оболочка в более высоких измерениях, нахождение вершин многогранника

Предположим, у меня есть облако точек, заданное в 6-мерном пространстве, которое я могу сделать настолько плотным, насколько это необходимо. Эти точки оказываются лежащими на поверхности многогранника меньшей размерности (т. е. точечные векторы (x1, x2, ... x6) оказываются компланарными).

Я хотел бы найти вершины этого неизвестного многогранника, и моя текущая попытка использует алгоритм qhull через интерфейс scipy в Python. Вначале я получал только сообщения об ошибках, по-видимому, вызванные вводом более низкого измерения и/или множеством вырожденных точек. Я попробовал пару методов грубой силы для устранения вырожденных точек, но не очень успешно, и поэтому, в конце концов, я предполагаю, что все эти точки должны лежать на выпуклой оболочке.

Этот вопрос был очень полезно, так как предполагает уменьшение размерности с помощью анализа основных компонентов. Если я проецирую точки на 4D-гиперплоскость, алгоритм qhull работает без ошибок (для любого более высокого измерения он не работает).

from scipy.spatial import ConvexHull
from sklearn.decomposition import PCA

model = PCA(n_components=4).fit(initial_points)
proj_points = model.transform(initial_points)
hull = ConvexHull(proj_points, qhull_options = "Qx")

В ответе на вопрос выше упоминается, что симплексы необходимо преобразовать обратно после вычисления выпуклой оболочки проецируемых точек. Но вывод qhull состоит только из индексов, и почему они не совпадают с индексами начальных точек?

Теперь моя проблема в том, что я не знаю, какую точность использовать для получения правильных вершин. Независимо от того, насколько плотным я создаю облако точек, полученные вершины различаются с разной точностью. Например, для начальных точек в массиве (10000, 6) я получаю (где E0,03 — максимум, для которого это работает):

hull1 = ConvexHull(proj_points, qhull_options = "Qx, E0.03")
print len(hull1.vertices)
print hull1.vertices

5
[ 437 2116 3978 7519 9381]

И начертить его в какой-нибудь (не очень информативной) проекции осей 0,1,2 (где синие точки представляют выборку начального облака точек):

введите здесь описание изображенияНо для большей точности (конечно) я получаю другой набор:

hull2 = ConvexHull(proj_points, qhull_options = "Qx, E0.003")
print len(hull2.vertices)
print hull2.vertices

29
[  74   75  436  437  756 1117 2116 2366 2618 2937 3297 3615 3616 3978 3979
 4340 4561 4657 4659 4924 5338 5797 6336 7519 7882 8200 9381 9427 9470]

Та же проекция (только немного другой ракурс):

введите здесь описание изображения

Я подозреваю, что на первом изображении недостаточно вершин, а на втором изображении, возможно, слишком много. Хотя, конечно, я не могу извлечь из этих графиков точную информацию. Но есть ли хороший способ узнать, какую точность использовать? Или, может быть, совершенно другой подход к этой проблеме (я уже попробовал несколько)?


person Denor    schedule 11.01.2015    source источник
comment
Увлекательный вопрос. У меня нет готового ответа, но согласен, что в первом примере определенно (на глаз) слишком мало вершин. Более поздний, я думаю, всегда будет иметь много вершин по краям (извините меня за плохую терминологию, а не в мою область знаний) вашего спроецированного многогранника только потому, что начальные точки случайны - вы вряд ли получите один на истинной вершине многогранника, который, как вы говорите, существует. Если у вас есть время поэкспериментировать, пробовали ли вы вариант Q8? который, кажется, игнорирует почти внутренние точки.   -  person J Richard Snape    schedule 27.01.2015
comment
Спасибо за комментарий. Оказывается, большинство различных вариантов в Qhull дают одинаковые (разные) ответы, как и Q8. Единственный, который дает немного другое число (но все еще нестабильное с разной точностью), это Q9. Верно то, что набор вряд ли будет содержать ожидаемые истинные вершины, но, поскольку они подходят очень близко, я чувствую, что должен быть способ их получить.   -  person Denor    schedule 29.01.2015
comment
Чем больше я думаю, тем больше я заинтригован. Кажется, это все еще предмет статей по математике. Это показывает подход (2D), где их альфа-параметр, похоже, имеет аналогичный эффект для вашей точности. Проблема в том, что оболочка по определению является наименьшим многогранником, который может содержать точки, и все же мы предполагаем, что истинные вершины могут лежать за пределами выборки, и что, в некотором смысле, многогранник имеет более простая форма, чем полученная при высокоточной оценке. На глазок, ок, алгоритмически сложно.   -  person J Richard Snape    schedule 29.01.2015
comment
Да, я вижу сходство в связанной статье, довольно приятное, даже если «недоступность» возникает только в более высоких измерениях. Более того, потому что любой другой подход к сравнению точек потерпел неудачу (то есть точечные произведения и т. д.). В некотором смысле подход выпуклой оболочки к этой проблеме, скорее всего, не является тем, для чего оптимизирован алгоритм, хотя бы потому, что каждая точка в этом облаке точек фактически будет частью оболочки. Тем не менее, я не программист, и поэтому я решил дважды проверить здесь, если я что-то упустил. Видеть, что это вполне может быть открытым, тоже открытие, я полагаю.   -  person Denor    schedule 29.01.2015
comment
Я не совсем понял значение всех точек, находящихся на корпусе: возможно, можно было бы использовать методы для идентификации (гипер)плоскостей в облаке точек. Пересечение таких плоскостей может дать вам простой корпус, который вы ищете. Можно было потом проверить, что все точки были на или внутри. Я нашел алгоритм RANSAC, приведенный для этого . 1, 2   -  person J Richard Snape    schedule 03.02.2015
comment
О, здорово, спасибо! Я находился в процессе поиска векторов нормали к каждой плоскости вручную, но алгоритм RANSAC тоже кажется многообещающим. Я посмотрю на это.   -  person Denor    schedule 04.02.2015
comment
Нет проблем - дайте мне знать, если это сработает. Если это так, мы можем отредактировать обсуждение в ответ на случай, если это будет полезно для кого-то в будущем.   -  person J Richard Snape    schedule 04.02.2015
comment
Несмотря на опоздание, я должен признать, что не нашел способа реализовать алгоритм RANSAC в более высоких измерениях. Возможно, есть способ сделать это, обобщая приведенные идеи, но я не мог с этим справиться.   -  person Denor    schedule 18.02.2015
comment
Неважно, я думаю, что алгоритм, описанный @timothyshields ниже, делает то, что вы хотите, используя вместо этого градиентный спуск.   -  person J Richard Snape    schedule 22.02.2015


Ответы (1)


В этом ответе я предполагаю, что вы уже использовали PCA для сжатия данных почти без потерь до 4-мерных данных, где уменьшенные данные лежат в 4-мерном многограннике с концептуально небольшим количеством граней. Я опишу подход к решению граней этого многогранника, который, в свою очередь, даст вам вершины.

Пусть xi в R4, i = 1, ..., m, будет точками данных, уменьшенными с помощью PCA.

Пусть F = (a, b) — грань, где a находится в R4, a a = 1, а b — в R.

Мы определяем функцию потеря грани L следующим образом, где +, - > 0 — параметры, которые вы выбираете. + должно быть очень маленьким положительным числом. - должно быть очень большим положительным числом.

L(F) = суммаi(+ max(0, axi + b) - - min( 0, ахi + б))

Мы хотим найти минимальные грани F относительно функции потерь L. Небольшой набор всех минимальных граней будет описывать ваш многогранник. Вы можете найти минимальные грани, случайным образом инициализировав F и затем выполнив градиентный спуск, используя частные производные ∂L / ∂aj, j = 1, 2, 3, 4 и ∂L / ∂b. На каждом шаге градиентного спуска ограничьте a равным 1 путем нормализации.

∂L / ∂aj = суммаi(+ xj [axi > + b > 0] - - xj [axi + b ‹ 0]) для j = 1, 2, 3, 4

∂L / ∂b = суммаi(+ [axi + b > 0] - - [ax i + b ‹ 0])

Обратите внимание на скобки Айверсона: [P] = 1, если P верно, и [P] = 0, если P является ложным.

person Timothy Shields    schedule 10.02.2015
comment
Есть пара деталей, которые все еще ускользают от меня в отношении фактического применения, но в теории мне очень нравится эта идея. Для начала должен признаться, что мне не совсем понятно, как получить лица. Не могли бы вы объяснить (или указать мне на какой-нибудь источник), откуда берется условие a • a = 1? - person Denor; 18.02.2015
comment
Вектор a является нормалью (направленной) грани F. Условие a • a = 1 просто ограничивает длину нормали a равной 1; то есть ||а|| = 1. - person Timothy Shields; 18.02.2015
comment
Ах, верно. В этом есть смысл. Чем именно определяется b? Я еще не полностью реализовал идею, но полагаю, имеет смысл принять это. - person Denor; 21.02.2015
comment
b — смещение грани F по нормали a. Когда b = 0, грань проходит через начало координат. Когда b = 5, грань находится на расстоянии 5 от начала координат. - person Timothy Shields; 21.02.2015
comment
@Denor Я добавил частичные градиенты в конец ответа. - person Timothy Shields; 21.02.2015