【问题标题】:Implementing SVM RBF实现 SVM RBF
【发布时间】:2020-09-26 06:26:01
【问题描述】:

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

有什么好的资源可以帮助我吗?我需要学习哪些技能才能实现这一目标? 您是否推荐任何易于理解机器学习主要概念的书籍作为初学者的入门书籍?

非常感谢。

【问题讨论】:

  • 嗨。 sklearn SVM-RBF(或 SVC-RBF)正在使用 libsvm。该论文可通过here 获取。你需要有一些线性代数的知识。懂c++的也可以查看实现代码here
  • 嗨,谢谢。是的,我在线性代数方面有一些背景,我一直在这方面阅读。我想在 python 中实现 svm-rbf 而不是在 c++ 中。

标签: python svm


【解决方案1】:

这种类型的 SVM 通常使用 SMO 算法实现。 您可能需要检查原始发布版本(Platt, John。Fast Training of Support Vector Machines using Sequential Minimal Optimization,在内核方法支持向量学习的进展中,B. Scholkopf, C. Burges, A . Smola, eds., MIT Press (1998)),但对我来说相当复杂。

Stanford Lecture Notes 提供了一个稍微简化的版本,但所有公式的推导应该在其他地方找到(例如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

【讨论】:

  • 非常感谢。这将是了解 SVM 的良好开端。
猜你喜欢
  • 2017-06-13
  • 2018-03-07
  • 2021-12-24
  • 2020-05-18
  • 1970-01-01
  • 2016-07-17
  • 2021-10-15
  • 2014-03-15
  • 2020-10-14
相关资源
最近更新 更多