Я пытался понять SVM из здесь . Разбираясь в ядрах, я наткнулся на следующий сюжет. (построено мной согласно данным, приведенным в здесь )
Используя эти данные и cvxopt.solvers
, я получил параметр w
и b
. используя следующий код python, где я использую полиномиальное ядро степени 2 и получил границу решения, как показано на графике рядом с кодом.
import numpy as np
from succinctly.datasets import get_dataset, non_separable_poly as nsp
import matplotlib.pyplot as plt
from cvxopt import matrix as cvxopt_matrix
import cvxopt.solvers
C=1000 #hard margin
X_data, y_data = get_dataset(nsp.get_training_examples)
x1= np.arange(0,20,1)
degree=2
def compute_w(multipliers, X, y):
return np.sum(multipliers[i] * y[i] * X[i]for i in range(len(y)))
def compute_b(w, X, y):
return np.sum([y[i] - np.dot(w, X[i])for i in range(len(X))])/len(X)
def polynomial_kernel(a, b, degree, constant=0):
result = sum([a[i] * b[i] for i in range(len(a))]) + constant
return pow(result, degree)
def decision_boundary(x_1,w,b,degree):
if degree==1:
b1=b
a1= -w[0]/w[1]
c1=-b1/w[1]
y1=a1*x1+c1
return y1
elif degree>1:
y1= np.sqrt(w[0]*x_1**2 + w[1]*x_1**1 + b + np.log(128))
return y1[::-1]
m = X_data.shape[0]
# Gram matrix - The matrix of all possible inner products of X.
K = np.array([polynomial_kernel(X_data[i], X_data[j],degree)for j in range(m) for i in range(m)]).reshape((m, m))
P = cvxopt.matrix(np.outer(y_data, y_data) * K)
q = cvxopt.matrix(-1 * np.ones(m))
# Equality constraints
A = cvxopt.matrix(y_data, (1, m))
b = cvxopt.matrix(0.0)
# Inequality constraints
G = cvxopt_matrix(np.vstack((np.eye(m)*-1,np.eye(m))))
h = cvxopt_matrix(np.hstack((np.zeros(m), np.ones(m) * C)))
# Solve the problem
solution = cvxopt.solvers.qp(P, q, G, h, A, b)
# Lagrange multipliers
multipliers = np.ravel(solution['x'])
# Support vectors have positive multipliers.
has_positive_multiplier = multipliers > 1e-7
sv_multipliers = multipliers[has_positive_multiplier]
support_vectors = X_data[has_positive_multiplier]
support_vectors_y = y_data[has_positive_multiplier]
w = compute_w(multipliers, X_data, y_data)
b = compute_b(w, support_vectors, support_vectors_y)
a0=X_data[0:8,0]
b0=X_data[0:8,1]
c0=X_data[8:16,0]
d0=X_data[8:16,1]
fig = plt.figure(figsize=(6,6))
plt.plot(a0,b0,"r^",c0,d0,"b*",markersize=8)
# Adding decision boundary to plot
bound = decision_boundary(x1,w,b,degree)
plt.plot(x1, bound, 'k', lw=1)
plt.title('Figure 6:A straight line cannot separate the data',fontsize=14)
plt.xlabel(r'$x$',fontsize=14)
plt.ylabel(r'$y$',fontsize=14)
# Turn on the minor TICKS, which are required for the minor GRID
plt.minorticks_on()
# Customize the major grid
plt.grid(which='major', linestyle='-', linewidth='0.3', color='black')
# Customize the minor grid
plt.grid(which='minor', linestyle=':', linewidth='0.3', color='black')
plt.legend(["Class0", "Class1"], loc="upper right",prop=dict(size=8))
plt.ylim(0,20)
plt.xlim(0,20)
plt.show()
, но я хочу построить границу нелинейного решения, которая может разделять данные, как показано ниже.
Я знаю, что нужно выбрать правильное полиномиальное уравнение, но как его найти и построить границу решения? Примечание: из здесь Мне пришло в голову построить границу нелинейного решения