Skip to content

Instantly share code, notes, and snippets.

@nguyenhaidang94
Last active May 5, 2022 15:18
Show Gist options
  • Save nguyenhaidang94/000ef0d2759cb632fa31780f3b515edb to your computer and use it in GitHub Desktop.
Save nguyenhaidang94/000ef0d2759cb632fa31780f3b515edb to your computer and use it in GitHub Desktop.
import cvxopt
import numpy as np
from .base import BaseModel
class SVM(BaseModel):
def __init__(self):
self._w = None
self._b = None
def train(self, X: np.ndarray, y: np.ndarray):
n_samples, _ = X.shape
# compute inputs for cvxopt solver
K = (X * y[:, np.newaxis]).T
P = cvxopt.matrix(K.T.dot(K)) # P has shape n*n
q = cvxopt.matrix(-1 * np.ones(n_samples)) # q has shape n*1
G = cvxopt.matrix(-1 * np.identity(n_samples)) # G is diagonal matrix
h = cvxopt.matrix(np.zeros(n_samples))
A = cvxopt.matrix(1.0 * y, (1, n_samples))
b = cvxopt.matrix(0.0)
# solve quadratic programming
cvxopt.solvers.options['show_progress'] = False
solution = cvxopt.solvers.qp(P, q, G, h, A, b)
_lambda = np.ravel(solution['x'])
# find support vectors
S = np.where(_lambda > 1e-10)[0] # lambda is closed to zero
self._w = K[:, S].dot(_lambda[S])
self._b = np.mean(y[S] - X[S, :].dot(self._w))
def predict(self, X: np.ndarray) -> np.ndarray:
"""
Return +1 for positive class and -1 for negative class.
"""
results = np.sign(X.dot(self._w) + self._b)
results[results == 0] = 1
return results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment