Я пытаюсь сгенерировать разделяющую гиперплоскость двоичной классификации для трехмерных точек.
Вот мои точки, которые линейно разделимы.
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