Определите, являются ли эти два класса линейно разделяемыми (алгоритмически в 2D)
Существует два класса, назовем их X и O. Ряд элементов, принадлежащих этим классам, разложен в плоскости xy. Вот пример, где два класса не являются линейно разделяемыми. Невозможно провести прямую линию, которая отлично разделяет Xs и Os на каждой стороне линии.
![Members of two classes spread out on the xy-plane]()
Как определить, в принципе, являются ли эти два класса линейно разделяемыми?. Меня интересует алгоритм, в котором не делается никаких предположений относительно количества элементов или их распределения. Предпочтительным является алгоритм наименьшей вычислительной сложности.
Ответы
Ответ 1
Если вы нашли выпуклую оболочку как для точек X
, так и для точек O
отдельно (т.е. на этом этапе у вас есть два отдельных выпуклых корпуса), вам просто нужно будет проверить, пересекаются ли какие-либо сегменты корпуса или либо корпус был заключен другим.
Если бы два корпуса были полностью непересекающимися, два набора данных были бы геометрически разделяемыми.
Поскольку оболочки по определению выпуклы, любой разделитель будет прямой.
Существуют эффективные алгоритмы, которые могут использоваться как для поиска выпуклой оболочки (алгоритм qhull основан на O(nlog(n))
quickhull), а также выполнить тесты пересечения линии для набора сегментов (sweepline в O(nlog(n))
), поэтому В целом кажется, что эффективный алгоритм O(nlog(n))
должен быть возможен.
Этот тип подхода также должен обобщать на общие тесты тестирования k-way
(где у вас есть k
группы объектов) путем формирования выпуклой оболочки и выполнения тестов пересечения для каждой группы.
Он также должен работать в более высоких измерениях, хотя тесты пересечения стали бы более сложными...
Надеюсь, что это поможет.
Ответ 2
В вычислительном отношении наиболее эффективный способ определить, являются ли два набора точек линейно разделимыми, - это применить линейное программирование. GLTK идеально подходит для этой цели, и почти каждый язык высокого уровня предлагает интерфейс для него - R, Python, Octave, Julia и т.д.
Допустим, у вас есть набор точек A и B:
![enter image description here]()
Затем вы должны минимизировать 0 для следующих условий:
(А ниже - это матрица, а не набор точек сверху)
![enter image description here]()
"Минимизация 0" фактически означает, что вам не нужно на самом деле оптимизировать целевую функцию, потому что нет необходимости выяснять, являются ли множества линейно разделимыми.
В конце (
) определяется разделительная плоскость.
![enter image description here]()
Если вы заинтересованы в рабочем примере по R или математическим деталям, проверьте это.
Ответ 3
Вот наивный алгоритм, который, я уверен, сработает (и, если это так, показывает, что проблема не является NP-полной, как утверждает другая статья), но я не удивлюсь, если это можно сделать более эффективно: если существует разделительная линия, можно будет перемещать и поворачивать ее до тех пор, пока она не попадет на два из X'es или один X и один О. Поэтому мы можем просто взглянуть на все возможные линии, которые пересекают два X ' es или один X и один O, и посмотрите, является ли какая-либо из них разделительными линиями. Итак, для каждой из пар O (n ^ 2), итерации по всем n-2 другим элементам, чтобы увидеть, все ли X'es находятся с одной стороны, и все O на другом. Общая временная сложность: O (n ^ 3).
Ответ 4
Линейный персептрон может найти такое разделение, если оно существует.
Смотрите: http://en.wikipedia.org/wiki/Perceptron.
Ответ 5
Вычисляя линейный SVM, затем определяя, на какой стороне вычисленной плоскости с оптимальными маргиналами каждая точка лежит, скажет вам, являются ли точки линейно разделяемыми.
Это слишком много, но если вам нужно быстрое одно решение, есть много существующих библиотек SVM, которые сделают это для вас.
Ответ 6
Вероятно, вы можете применить линейное программирование к этой проблеме. Я не уверен в своей вычислительной сложности в формальных выражениях, но эта техника успешно применяется к очень большим проблемам, охватывающим широкий диапазон областей.
Ответ 7
Как уже упоминалось ElKamina, Linear Perceptron гарантированно найдет решение, если оно существует. Этот подход неэффективен для больших размеров. Вычислительно наиболее эффективным способом решить, являются ли два набора точек линейно разделяемыми, является применение линейного программирования.
Код с примером для решения проблемы с использованием Perceptron в Matlab здесь
Ответ 8
В общем, проблема NP-hard, но есть хорошие приближенные решения, такие как K-означает кластеризацию.
Ответ 9
Ну, и Perceptron, и SVM (Машины опорных векторов) могут определить, являются ли два набора данных линейно разделимыми, но SVM может найти оптимальную гиперплоскость разделения. Кроме того, он может работать с n-мерными векторами, а не только с точками.
Он используется в таких приложениях, как распознавание лиц. Я рекомендую углубиться в эту тему.