实现 SVM RBF

Implementing SVM RBF

我是数据科学领域的新手,我知道如何使用 sklearn 库以及如何自定义 RBF 内核,但我想从头开始实现 SVM-RBF 内核以用于学习目的以及如何手动实现拟合和预测不使用 sklearn 库。

有什么好的资源可以帮到我吗?我需要学习哪些技能才能实现这一目标? 有没有推荐一些简单易懂的机器学习主要概念的入门书籍作为入门书?

非常感谢。

这种类型的 SVM 通常用 SMO 算法实现。 您可能需要查看原始发布版本(Platt, John。使用顺序最小优化 快速训练支持向量机,在内核方法支持向量学习的进展中,B. Scholkopf,C. Burges, A. Smola, eds., MIT Press (1998)), 但对我来说是相当复杂的。

Stanford Lecture Notes, but derivation of all the formulas should be found somewhere else (e.g. this random notes I found on the Internet).

中提供了一个稍微简化的版本

作为替代方案,我可以向您推荐我自己的 SMO 算法变体。 高度简化,实现包含 30 多行代码

class SVM:
  def __init__(self, kernel='linear', C=10000.0, max_iter=100000, degree=3, gamma=1):
    self.kernel = {'poly':lambda x,y: np.dot(x, y.T)**degree,
                   'rbf':lambda x,y:np.exp(-gamma*np.sum((y-x[:,np.newaxis])**2,axis=-1)),
                   'linear':lambda x,y: np.dot(x, y.T)}[kernel]
    self.C = C
    self.max_iter = max_iter

  def restrict_to_square(self, t, v0, u):
    t = (np.clip(v0 + t*u, 0, self.C) - v0)[1]/u[1]
    return (np.clip(v0 + t*u, 0, self.C) - v0)[0]/u[0]

  def fit(self, X, y):
    self.X = X.copy()
    self.y = y * 2 - 1
    self.lambdas = np.zeros_like(self.y, dtype=float)
    self.K = self.kernel(self.X, self.X) * self.y[:,np.newaxis] * self.y
    
    for _ in range(self.max_iter):
      for idxM in range(len(self.lambdas)):
        idxL = np.random.randint(0, len(self.lambdas))
        Q = self.K[[[idxM, idxM], [idxL, idxL]], [[idxM, idxL], [idxM, idxL]]]
        v0 = self.lambdas[[idxM, idxL]]
        k0 = 1 - np.sum(self.lambdas * self.K[[idxM, idxL]], axis=1)
        u = np.array([-self.y[idxL], self.y[idxM]])
        t_max = np.dot(k0, u) / (np.dot(np.dot(Q, u), u) + 1E-15)
        self.lambdas[[idxM, idxL]] = v0 + u * self.restrict_to_square(t_max, v0, u)
    
    idx, = np.nonzero(self.lambdas > 1E-15)
    self.b = np.sum((1.0-np.sum(self.K[idx]*self.lambdas, axis=1))*self.y[idx])/len(idx)
  
  def decision_function(self, X):
    return np.sum(self.kernel(X, self.X) * self.y * self.lambdas, axis=1) + self.b

在简单的情况下效果并不比sklearn.svm.SVC高多少,对比如下

我已将此代码与更多生成图像的代码一起发布,以便在 GitHub 上进行比较。 有关公式的更详细说明,您可能需要参考 my preprint on ResearchGate.

更新:现在可以使用实时版本,请参阅Github Pages