使用SVM RBF实现

3

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

有没有好的资源可以帮助我?我需要学习什么技能才能实现这个?你推荐哪些对于初学者来说易于理解机器学习主要概念的简单易懂的书籍作为起点呢?

非常感谢。


嗨。sklearn SVM-RBF(或SVC-RBF)使用libsvm。该论文可在此处获得(https://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.pdf)。您需要具备一定的线性代数知识。如果您了解c ++,还可以在此处检查实现代码(https://github.com/cjlin1/libsvm)。 - Yohanes Gultom
嗨,谢谢。是的,我有一些线性代数的背景,并且一直在这个领域阅读。我想在Python中实现svm-rbf,而不是在C++中。 - Angelus
1个回答

4
这种类型的SVM通常使用SMO算法实现。您可能需要查看原始出版版本(Platt, John. Fast Training of Support Vector Machines using Sequential Minimal Optimization, in Advances in Kernel Methods Support Vector Learning, B. Scholkopf, C. Burges, A. Smola, eds., MIT Press (1998)),但对我来说太复杂了。 斯坦福讲义中提供了一个简化版本,但所有公式的推导都应该在其他地方找到(例如我在互联网上找到的这些随机笔记)。
作为替代,我可以提供我的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差,下面是对比结果enter image description here
我已经发布了这段代码,并添加了一些产生图像以供比较的代码,可以在GitHub上找到。
如果您需要更详细的解释和公式,请参考我的ResearchGate预印本更新:现在有一个在线版本可用,请查看Github Pages

非常感谢。学习支持向量机将是一个很好的开始。 - Angelus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接