SVM --从“原理”到实现

article/2025/10/1 3:25:33

零.

        本文所有代码均能在我 github上的 DML 找到,顺便求点Star

一.引入

        从一开始接触机器学习,就感觉SVM(支持向量机 Support Vector Machine)就是高端大气上档次的代名词啊,在深度学习出来之前一直都力压ANN一头,是应用得最好的算法了,本文借着实现DML的机会实现一下。


二.原理

       SVM的文章先不说论文和书啦,博文也是不少,所以我觉得实在不用在这里赘述这些了,这是标题里原理打引号的原因……

       现推荐这些博客里讲的SVM,我认为写得是极好的:

                     JerryLead 的五篇  很好理解

                     july的博客 ,还是那啥的风格,大长篇……事实上我没看完这个…只是觉得挺全的


       除此之外还可以去看看《统计学习方法》的内容


三.过程.

       接下来讲一下我选择实现的SOM的基本过程吧:

       SMO是(Sequential minimal optimization),其优化过程就是每次选取两个优化变量α(i)和α(j),然后更新α,直到满足停机条件为止:

       我基本上是按照《统计学习方法》来实现的,所以也就直接贴一下这上面的过程:

      

         至于alpha的选择,第一个变量的选择是要选择违反KKT条件的:

         

          代码的这里不是直接这样实现的,因为用了Ei,为了方便形式有所改变,但你可以推一下是没问题的:

         第二个变量的选择是选择使|Ei-Ej|最大的,然后按照一定的规则计算和更新就行了


四.实现与测试

        这是DML/SVM/svm.py

from __future__ import division
import numpy as np
import scipy as sp
from dml.tool import sign
import matplotlib.pyplot as plt
from numpy.random import random
import random as rd
class SVMC:def Gauss_kernel(x,z,sigma=2):return np.exp(-np.sum((x-z)**2)/(2*sigma**2))def Linear_kernel(x,z):return np.sum(x*z)def __init__(self,X,y,C=10,tol=0.01,kernel=Linear_kernel):'''X is n N*M matrix where N is #features and M is #train_case'''self.X=np.array(X)self.y=np.array(y).flatten(1)self.tol=tolself.N,self.M=self.X.shapeself.C=Cself.kernel=kernelself.alpha=np.zeros((1,self.M)).flatten(1)self.supportVec=[]self.b=0self.E=np.zeros((1,self.M)).flatten(1)def fitKKT(self,i):if ((self.y[i]*self.E[i]<-self.tol) and (self.alpha[i]<self.C)) or \(((self.y[i]*self.E[i]>self.tol)) and (self.alpha[i]>0)):return Falsereturn True	def select(self,i):pp=np.nonzero((self.alpha>0))[0]if (pp.size>0):j=self.findMax(i,pp)else:j=self.findMax(i,range(self.M))return jdef randJ(self,i):j=rd.sample(range(self.M),1)while j==i:j=rd.sample(range(self.M),1)return j[0]def findMax(self,i,ls):ansj=-1maxx=-1self.updateE(i)for j in ls:if i==j:continueself.updateE(j)deltaE=np.abs(self.E[i]-self.E[j])if deltaE>maxx:maxx=deltaEansj=jif ansj==-1:return self.randJ(i)return ansjdef InerLoop(self,i,threshold):j=self.select(i)#print i,j,self.y[i]==self.y[j],self.alpha[i],self.alpha[j],self.C#print self.y[i],self.y[j]self.updateE(j)self.updateE(i)if (self.y[i]==self.y[j]):L=max(0,self.alpha[i]+self.alpha[j]-self.C)H=min(self.C,self.alpha[i]+self.alpha[j])else:L=max(0,self.alpha[j]-self.alpha[i])H=min(self.C,self.C+self.alpha[j]-self.alpha[i])#print L,Ha2_old=self.alpha[j]a1_old=self.alpha[i]#print i,j#if L==H:#	return TrueK11=self.kernel(self.X[:,i],self.X[:,i])K22=self.kernel(self.X[:,j],self.X[:,j])K12=self.kernel(self.X[:,i],self.X[:,j])eta=K11+K22-2*K12if eta==0:return Trueself.alpha[j]=self.alpha[j]+self.y[j]*(self.E[i]-self.E[j])/etaif self.alpha[j]>H:self.alpha[j]=Helif self.alpha[j]<L:self.alpha[j]=Lif np.abs(self.alpha[j]-a2_old)<threshold:#print np.abs(a2_new-self.alpha[j])return True#print np.abs(a2_new-self.alpha[j]),"improve"self.alpha[i]=self.alpha[i]+self.y[i]*self.y[j]*(a2_old-self.alpha[j])b1_new=self.b-self.E[i]-self.y[i]*K11*(self.alpha[i]-a1_old)-self.y[j]*K12*\(self.alpha[j]-a2_old)b2_new=self.b-self.E[j]-self.y[i]*K12*(self.alpha[i]-a1_old)-self.y[j]*K22*\(self.alpha[j]-a2_old)#print a1_new,"a1 new"#print a2_new,"a2 new"if self.alpha[i]>0 and self.alpha[i]<self.C:self.b=b1_newelif self.alpha[j]>0 and self.alpha[j]<self.C:self.b=b2_newelse: self.b=(b1_new+b2_new)/2#self.alpha[i]=a1_new#self.alpha[j]=a2_newself.updateE(j)self.updateE(i)return Falsepassdef updateE(self,i):#self.supportVec=np.nonzero((self.alpha>0))[0]self.E[i]=0for t in range(self.M):#for t in range(self.M):self.E[i]+=self.alpha[t]*self.y[t]*self.kernel(self.X[:,i],self.X[:,t])self.E[i]+=self.b-self.y[i]def train(self,maxiter=100,threshold=0.000001):iters=0flag=Falsefor i in range(self.M):self.updateE(i)while (iters<maxiter) and (not flag):flag=Truetemp_supportVec=np.nonzero((self.alpha>0))[0]iters+=1for i in temp_supportVec:self.updateE(i)if (not self.fitKKT(i)):flag=flag and self.InerLoop(i,threshold)#if not flag:breakif (flag):for i in range(self.M):self.updateE(i)if (not self.fitKKT(i)):flag= flag and self.InerLoop(i,threshold)#if not flag:break		print "the %d-th iter is running" % itersself.supportVec=np.nonzero((self.alpha>0))[0]def predict(self,x):w=0for t in self.supportVec:w+=self.alpha[t]*self.y[t]*self.kernel(self.X[:,t],x).flatten(1)w+=self.breturn sign(w)def pred(self,X):test_X=np.array(X)y=[]for i in range(test_X.shape[1]):y.append(self.predict(test_X[:,i]))return ydef error(self,X,y):py=np.array(self.pred(np.array(X))).flatten(1)#print y,pyprint "the #error_case is  ",np.sum(py!=np.array(y))def prints_test_linear(self):w=0for t in self.supportVec:w+=self.alpha[t]*self.y[t]*self.X[:,t].flatten(1)w=w.reshape(1,w.size)print np.sum(sign(np.dot(w,self.X)+self.b).flatten(1)!=self.y),"errrr"#print w,self.bx1=0y1=-self.b/w[0][1]y2=0x2=-self.b/w[0][0]plt.plot([x1+x1-x2,x2],[y1+y1-y2,y2])#plt.plot([x1+x1-x2,x2],[y1+y1-y2-1,y2-1])plt.axis([0,30,0,30])for i in range(self.M):if  self.y[i]==-1:plt.plot(self.X[0,i],self.X[1,i],'or')elif  self.y[i]==1:plt.plot(self.X[0,i],self.X[1,i],'ob')for i in self.supportVec:plt.plot(self.X[0,i],self.X[1,i],'oy')plt.show()

试验一下结果:

      使用类似如下的代码:

svms=SVMC(X,y,kernel=Gauss_kernel)
svms.train()
print len(svms.supportVec),"SupportVectors:"for i in range(len(svms.supportVec)):t=svms.supportVec[i]print svms.X[:,t]
svms.error(X,y)
      完整的测试代码参见: DML/test/svm_test

     线性的:

     

     高斯的:你要自己写个高斯核

      

def Gauss_kernel(x,z,sigma=1):return np.exp(-np.sum((x-z)**2)/(2*sigma**2))
svms=SVMC(X,y,kernel=Gauss_kernel)
使用的测试数据:     

结果:


          

五.参考

      【1】《统计学习方法》

      【2】 JerryLead 的五篇

      【3】一个Java的实现 :点击打开链接

      

       

       

        

           


http://chatgpt.dhexx.cn/article/bT9MW8nd.shtml

相关文章

SVM算法详解

Support Vector Machine 终于&#xff0c;我们来到了SVM。SVM是我个人感觉机器学习中最优美的算法&#xff0c;这次我们要来非常细致地介绍。SVM是一类有监督的分类算法&#xff0c;它的大致思想是&#xff1a;假设样本空间上有两类点&#xff0c;我们希望找到一个划分超平面&…

SVM简介

SVM 文章目录 SVM一. 什么是SVM1. 简介2.SVM分类 二. 详细介绍1. 线性可分SVM1.1 支撑点&#xff0c;支撑向量1.2 分割超平面与间隔最大化1.3 线性可分SVM的目标函数以及相关算法1.4 线性可分SVM的简单举例 2.线性SVM2.1 为什么需要线性SVM2.2 线性SVM相关理论2.3 线性SVM算法 …

Svm算法原理及实现

Svm&#xff08;support Vector Mac&#xff09;又称为支持向量机&#xff0c;是一种二分类的模型。当然如果进行修改之后也是可以用于多类别问题的分类。支持向量机可以分为线性核非线性两大类。其主要思想为找到空间中的一个更够将所有数据样本划开的超平面&#xff0c;并且使…

SVM 原理详解,通俗易懂

看了该作者的文章&#xff0c;瞬间膜拜了&#xff01;讲得太好了&#xff01; 转自&#xff1a;http://www.blogjava.net/zhenandaci/category/31868.html &#xff08;一&#xff09;SVM的简介 支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的&…

机器学习笔记6:SVM基本原理

SVM的基本原理&#xff1a; 1、最大间隔原则 2、对偶表示 3、KKT条件 SVM(Support Vector Machine)&#xff0c;又称支持向量机&#xff0c;在分类问题上&#xff0c;除了logistic分类回归外&#xff0c;还有另一种实现方式&#xff0c;那就是使用SVM原则。那么什么是SVM 呢。…

SVM原理

我们先认识一下SVM&#xff1a; &#xff08;1&#xff09;支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种对数据进行二分类的广义线性分类器&#xff0c;其分类边界是对学习样本求解的最大间隔超平面。 &#xff08;2&#xff09;SVM使用铰链损失函数…

通俗易懂SVM原理介绍,适合小白食用

目录 1、SVM概念描述 2、SVM数学表达及相关计算 3、SVM优化问题定义 附&#xff1a;证明区 【证明1】 【计算1】 1、SVM概念描述 如图一所示&#xff0c;存在两个数据集&#xff0c;我们希望通过一个超平面将两个数据集分割开&#xff0c;并且我们希望这个超平面离两个数…

01-Hive创建表

声明&#xff1a;本实验环境是Apache hadoop-2.2.0&#xff0c;zookeeper-3.4.5&#xff0c;mysql Server version: 5.1.73作为元数据库&#xff0c;hive版本是apache-hive-0.9.0-bin&#xff0c;都是apache&#xff0c;不是CDH和其他。本实验集群3台&#xff0c;一个主节点(ha…

hive 中创建表的三种方式

官网地址&#xff1a;https://cwiki.apache.org/confluence/display/Hive/LanguageManualDDL 通常我们所使用的创建hive表有三种方式 1.create table 首先我们找到官网对创建表的描述如下&#xff1a; ’[]’ 表示可选&#xff0c;’|’ 表示几选一 CREATE [TEMPORARY] [EXT…

hive创建新表——基础

创建基础表 1、创建表&#xff1a; create table if not exists orders 创建一个名叫“orders”的表&#xff0c;“if not exists”可以写可不写&#xff0c;如果相同名字的表已经存在&#xff0c;则抛出异常&#xff0c;可以用 IF NOT EXIST 选项来忽略这个异常。 2、定义表…

HIVE的常用操作-建库和表-插入数据

hive的安装&#xff08;远程模式&#xff09; 点击打开链接 使用hive----------------------- 启动hadoop 启动hive 创建数据库&#xff1a; create database myhive; 查看数据库&#xff1a; hive (default)> show databases; OK database_name default myhive 数…

Hive三种建表语句详解

转载自&#xff1a;https://blog.csdn.net/qq_36743482/article/details/78383964 注&#xff1a;hive其他语法在hive官网有说明&#xff0c;建议初学者&#xff0c;去官网学习一手的资料&#xff0c; 官网&#xff1a;https://cwiki.apache.org/confluence/display/Hive/Home#…

关于hive建表查询语句小记

库相关操作 创建数据库 CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_nameproperty_value, ...)]; IF NOT EXISTS 也就是没有重复库就创建&#xff0c;有重复就不执行建库 保证了建库…

hive、pg库,建表语句及查询表结构语句

1、hive hive 建表语句 DROP TABLE IF EXISTS tmp_001; CREATE TABLE tmp_001 (etl_time timestamp comment , day_id double comment , subs_id string comment , msisdn int comment ) comment partitioned by…

3、Hive数据仓库——建表语句

文章目录 Hive基本操作Hive查看SQL解析计划Hive建表建表1&#xff1a;全部使用默认建表方式 Hive 内部表 &#xff08;Managed tables&#xff09;指定location (这种方式也比较常用)formatted 查看该表的结构化数据&#xff0c;但并不列出表中的数据将本地数据上传到HDfS上 Hi…

HIVE的三种建表方式

目录 一、直接建表二、as &#xff08;直接使用查询结果插入到一张新表&#xff09;三、like&#xff08;复制表结构&#xff09; 一、直接建表 中括号里面的均为可选项 CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name[(col_name data_type [COMMENT col_comment], ...…

Hive学习3:Hive三种建表语句详解

注&#xff1a;hive其他语法在hive官网有说明&#xff0c;建议初学者&#xff0c;去官网学习一手的资料&#xff0c; 官网&#xff1a;https://cwiki.apache.org/confluence/display/Hive/Home#Home-UserDocumentation Create Table 官网说明 Hive建表方式共有三种&#xff…

Hive_ Hive 建表语句详解

参考文章&#xff1a; https://blog.csdn.net/qq_36743482/article/details/78383964 最近博主在编写一个每天定时创建Hive 分区的脚本&#xff0c;其中需要创建Hive表&#xff0c; 开始的时候我以为创建Hive 表的语句顺序是比较宽松的&#xff0c;经过测试发现不然&#xf…

Hive建表语句详解--CREATE TABLE

创建表的三种方法 Hive创建表的方式&#xff08;默认路径/user/hive/warehouse&#xff0c;也可以location指定&#xff0c;主要针对external表&#xff09; 1、使用create命令创建一个新表,带分区 CREATE TABLE mydb.dept( dept_no int, addr string, tel string) par…

【Hive】Hive 创建表

学习笔记—Hive创建表 1. Hive语句的特点 HQL 语言大小写不敏感&#xff0c;但内容分大小写&#xff08;where ,if/ case when&#xff0c;如&#xff1a;数据表内容某人名叫Tom&#xff0c;则条件后不能写tom&#xff0c;HDFS 路径名&#xff08;NameNode&#xff09;分大小写…