Machine learning 实现线性、二进制SVM(支持向量机)

Machine learning 实现线性、二进制SVM(支持向量机),machine-learning,svm,Machine Learning,Svm,我想实现一个简单的SVM分类器,在高维二进制数据(文本)的情况下,我认为简单的线性SVM是最好的。我自己实现它的原因基本上是我想了解它是如何工作的,所以使用库不是我想要的 问题是,大多数教程都使用一个可以作为“二次问题”求解的方程,但它们从来没有显示实际的算法!所以,你能给我指一个我可以学习的非常简单的实现,或者(更好)指一个一直到实现细节的教程吗 非常感谢 John C.Platt在本文中发现了一些序列最小优化(SMO)方法的伪代码:。还有一个SMO算法的Java实现,它是为研究和教育目的而开

我想实现一个简单的SVM分类器,在高维二进制数据(文本)的情况下,我认为简单的线性SVM是最好的。我自己实现它的原因基本上是我想了解它是如何工作的,所以使用库不是我想要的

问题是,大多数教程都使用一个可以作为“二次问题”求解的方程,但它们从来没有显示实际的算法!所以,你能给我指一个我可以学习的非常简单的实现,或者(更好)指一个一直到实现细节的教程吗

非常感谢

John C.Platt在本文中发现了一些序列最小优化(SMO)方法的伪代码:。还有一个SMO算法的Java实现,它是为研究和教育目的而开发的()

解决QP优化问题的其他常用方法包括:

  • 约束共轭梯度
  • 内点法
  • 活动集方法

但是请注意,理解这些东西需要一些数学知识(拉格朗日乘数、卡鲁什-库恩-塔克条件等)。

您是否对使用内核感兴趣?没有核函数,解决这类优化问题的最佳方法是通过各种形式的随机梯度下降。中介绍了一个具有显式算法的好版本


显式算法不使用内核,但可以修改;然而,无论是在代码还是运行时复杂性方面,它都会更加复杂。

看看libsvm上的liblinear和非线性SVM

下面的文章“Pegasos:SVM的原始估计次梯度解算器”第11页顶部描述了Pegasos算法,该算法也适用于内核。可从


它似乎是坐标下降和次梯度下降的混合。此外,算法的第6行是错误的。在谓词中,第二次出现的y_i_t应替换为y_j。

我想补充一下关于普拉特原著的答案。 中提供了一个稍微简化的版本,但所有公式的推导应在其他地方找到(例如)

如果可以偏离最初的实现,我可以向您推荐我自己的SMO算法变体

类支持向量机:
定义初始值(self,kernel='linear',C=10000.0,max_iter=100000,degree=3,gamma=1):
self.kernel={'poly':λx,y:np.dot(x,y.T)**度,
“rbf”:λx,y:np.exp(-gamma*np.sum((y-x[:,np.newaxis])**2,axis=-1)),
“线性”:lambda x,y:np.dot(x,y.T)}[内核]
self.C=C
self.max\u iter=max\u iter
def限制_至_平方(自身、t、v0、u):
t=(np.clip(v0+t*u,0,self.C)-v0)[1]/u[1]
返回(np.clip(v0+t*u,0,self.C)-v0)[0]/u[0]
def配合(自、X、y):
self.X=X.copy()
self.y=y*2-1
self.lambdas=np.zero_like(self.y,dtype=float)
self.K=self.kernel(self.X,self.X)*self.y[:,np.newaxis]*self.y
对于范围内(自身最大值):
对于范围内的idxM(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]],轴=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.非零(自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_函数(self,X):
返回np.sum(self.kernel(X,self.X)*self.y*self.lambdas,axis=1)+self.b
在简单的情况下,它并不比sklearn.svm.SVC有多大价值,比较如下所示(我已经发布了生成这些图像的代码)


我使用了完全不同的方法推导公式,您可能需要查看详细信息。

我有数学背景,只是时间不多。。。谢谢你的回答!不,现在我只对线性支持向量机感兴趣。谢谢你的回答!你知道一个简单的关于内核的例子吗?我理解梯度下降,但内核更有趣。如果没有内核,它基本上是一个线性激活的感知器,不是吗?你至少应该添加到存储库的链接。