SVM: опорный вектор имеет запас 0? - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь сгенерировать разделяющую гиперплоскость двоичной классификации для трехмерных точек.

Вот мои точки, которые линейно разделимы.

Class 0: [[0,0,0], [0,1,1], [1,0,1], [0.5,0.4,0.4]]
Class 1: [[1,3,1], [2,0,2], [1,1,1]]

Начиная с sklearn.svm.SVC(kernel='linear'), производится следующее:

w = clf.coeff_ = [ 1.   0.5  0.5]
b = clf.intercept_ = -2.0
sv = clf.support_vectors_ = 
array([[ 0.,  1.,  1.],
       [ 1.,  0.,  1.],
       [ 2.,  0.,  2.],
       [ 1.,  1.,  1.]])

Понятно, что если w.dot(x)+b возвращает отрицательное значение, то x относится к классу 0; если положительное значение, то класс 1. Однако w.dot([1,1,1])+b = 0 !! Это означает, что [1,1,1], который является опорным вектором из класса 1, лежит на разделительной плоскости ..... в то время как никакие SV из класса 0 не лежат в sep. самолет.

ТАК МОЙ ВОПРОС ... ... 1020 *

Мои данные линейно разделимы, поэтому теоретически SVM должен иметь поля> 0 для обоих классов. Но здесь у моего SVM есть a = 0 для class1 и> 0 полей для class0. Почему это так? И если моя гиперплоскость неверна, как я могу вычислить правильную гиперплоскость? Спасибо.

КОД

from sklearn import svm
X0 = [[0,0,0], [0,1,1], [1,0,1], [0.5,0.4,0.4]]
Y0 = [0] * len(X0)
X1 = [[1,3,1], [2,0,2], [1,1,1]]
Y1 = [1] * len(X1)
X = X0 + X1
Y = Y0 + Y1
clf = svm.SVC(kernel='linear')
clf.fit(X, Y)
sv = clf.support_vectors_
w = clf.coef_[0] 
b = clf.intercept_[0]
print([w.dot(X0[i])+b for i in range(len(X0))]) # negative class
print([w.dot(X1[i])+b for i in range(len(X1))]) # positive class

1 Ответ

0 голосов
/ 17 мая 2018

ДА! Вы правы в своем объяснении, что, если w.dot(x)+b возвращает отрицательное значение, то x имеет класс 0;

Здесь следует подчеркнуть это более осторожно!

Классификация производится на основе ЗНАКА!

Это SIGNUM(w.dot([x])+b), w.dot([1, 1, 1]) + b = 0, 0 считается POSITIVE! и именно поэтому [1, 1, 1] считается класса 1

X1 = [[1,3,1], [2,0,2], [1,1,1]]

clf.predict(X1)

Вы получаете

array([1, 1, 1])

Для точек в 2D вы НАЧАЛА найдете линию, которая правильно разделяет данные. Эта линия называется границей решения! ТЕПЕРЬ В ЭТОЙ ГРАНИЦЕ РЕШЕНИЯ? w.dot([1, 1, 1]) + b = 0 Тогда то, что вы хотите сделать, - найти самую широкую область вокруг этой одной линии (называемую MARGIN / MAXIMUM SEPARATING HYPERPLANE / WIDEST ROAD), которая максимизирует расстояние между точками в двух классах!

Когда классы идеально отделимы?

На одном конце вашего поля, которые регулируются векторами поддержки? w.dot([1, 1, 1]) + b = -1

На другом конце вашего поля, которые регулируются векторами поддержки? w.dot([1, 1, 1]) + b = +1

НО, когда классы НЕ идеально разделимы? Вы можете иметь маржу, которая ИДЕАЛЬНО ЛОЖИТ НА СЕБЯ РЕШЕНИЯ! ЭТО ЗАВИСИТ ОТ ВАШИХ ДАННЫХ !, В вашем случае, одна часть вашего МАГНИТНОГО / МАКСИМАЛЬНОГО ОТДЕЛЕНИЯ ГИПЕРПАНИНЫ / САМЫЙ БОЛЬШОЙ ДОРОГИ лежит на ГРАНИЦЕ РЕШЕНИЯ! И ничего не поделаешь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...