SVM(support vector machine)
支持向量机是一种监督学习算法,可用于分类、回归、离群点检测。
引入软间隔因为:(1)不是任何任务都能找到好的核函数使其线性可分;(2)就算实现(1),但也无法判断模型线性可分是不是过拟合造成。
支持向量(support vector):到超平面最近的样本点间隔(margin):各异类支持向量到超平面的距离之和。硬间隔:要求所有样本点都满足约束条件(即所有样本点都划分准确)软间隔:允许少量样本点不满足约束条件。
SVM原理
SVM的核心原理就是要找到具有最大“间隔”的划分超平面。
问题描述:给定一个数据集D,对其进行分类,即找到一个划分超平面,将不同类别数据分开。但划分超平面可以有多种,从直观上我们可定希望超平面位于“正中间”(间隔最大),如下图。因为这个超平面对训练数据局部干扰的容忍性最好。因为实际上训练数据以外的数据可能比这些数据更接近超平面。而最大“间隔”的超平面所产生的结果是最鲁棒的,对未见示例的泛化能力最强。SVM的核心原理就是要找到具有最大“间隔”的划分超平面。
SVM主要思想
线性可分情况:
(1)假设划分超平面为
(2)计算间隔:
因为:由点到直线距离公式:样本点到划分平面距离为:
将样本类别y设定为-1与1,由直线性质可知,y=-1时>1;y=1时<1;
不妨设
即设支持向量离划分平面距离为1(因为我们是要使划分平面离两个类别都尽可能远,且位于尽可能中间,而支持向量是距离划分平面最近的点)。所以间隔为:
(3)目标:最大化间隔r,即最小化,还要满足约束条件
在约束条件下求极值用拉格朗日乘子法。
问题:求Z=f(x,y),在φ(x,y)=0时的最值。
解法:构造函数L(x,y)=f(x,y)+λφ(x,y),之后列出①Lx(x,y)=0;②Ly(x,y)=0;③φ(x,y);求出一组解(x,y,λ),(x,y)即为所求极值点。
构造:
拉格朗日乘子法
1、SVM是针对线性可分情况,对于线性不可分情况,可以通过使用非线性映射算法(核函数),将低维输入空间不可分样本转换为高维特征空间使其线性可分,再采用线性算法。使得样本的非线性特征进行线性分析成为可能。
2、基于结构风险最小化理论,在特征空间上构建划分超平面,使得学习器得到全局最优化,并且在整个样本空间的期望以某个概率满足一定上界。
利用sklearn通过SVM对数据分类
科学计算包sklearn中包含对SVM的实现,可以通过调用svm模块建模,具体步骤:
1、构建SVM分类器:用svm.SVC()方法,模型中可通过设置函数参数调整:
class sklearn.svm.SVC(C=1.0, kernel=’rbf’, degree=3, gamma=’auto’, coef0=0.0,shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape=’ovr’, random_state=None)
模块参数:
C表示惩罚参数;kernel用来指定核函数;degree表示多项式核函数的度,当且仅对kernel = ‘poly’的SVM模型有效,其他核函数模型可忽略该参数;probability ,boolean类型值,表示是否准许概率估计,默认是False;decision_function_shap:svm支持多分类,有ovr:one against rest一对多模式,即将某个类别与剩下所有类别当做两类建立分类器,共有k个分类器;ovo:one against one模式,两两类别间建立分类器,共k(k-1)/2个
2、通过模块的函数fit (X,y)用模型匹配训练数据训练
3、通过模块的函数predict(x)对测试数据预测分类情况
简单应用实例1:
from sklearn import svmX=[[1,2],[3,4]]y=[1,2]clf=svm.SVC()clf.fit(X,y)clf.predict([[1.4,1.8],[1,3]])#array([1, 1])
实例二:
数据集:sklearn中的iris数据集,这里只用到它的前两个特征:
前140个数据用于训练,后10个数据用于测试
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsfrom sklearn import svm#导入iris数据集iris = datasets.load_iris()#只考虑前两个特征即萼片的长度和宽度X = iris.data[:, :2]y = iris.target#训练集train_X = X[:-10]train_y = y[:-10]#测试集test_X = X[-10:]test_y = y[-10:]def createSVMmodel(X,y):'''创建SVM模型参数:X - 训练集的特征数据y - 训练集的类别返回值:clf - 创建的模型'''clf = Noneclf=svm.SVC()clf.fit(X,y)return clf#训练模型SVM = createSVMmodel(train_X,train_y)#预测pred = SVM.predict(test_X)print(pred)
4、得到SVM更多信息
predict(X)获取分类结果获得支持向量:类属性support_vectors,即距离超平面最近的样本点获得支持向量的索引:类属性support获得样本集到超平面的距离:decision_function(X),返回二维数组,行为样本大小,列为分类器个数,即划分类别,与decision_function_shape参数有关得到模型分类结果精确度(精确值):score(X,y),返回浮点数计算样本集的可能输出概率值:先将类参数probability设为true,再用predict_proba(X)或predict_log_proba(X)(取对数概率值),返回的是一个二维数组 (n_samples, n_classes)
用不同核函数SVM模型对线性不可分数据分类
上述例子都是针对线性可分进行分类的,但在实际中,样本数据大多是线性不可分的。对于线性不可分数据,首先SVM在低维空间完成计算,然后借助核函数,将输入空间映射到高维度,然后在高维度特征空间中构造最佳划分平面。
特征空间的好坏对SVM的性能十分重要,因为我们希望在特征空间线性可分。而核函数显示定义了特征空间,所以核函数的选择十分重要。核函数有:线性核、多项式核、高斯核、拉普拉斯核、sigmoid核等,本文主要介绍前三种用法。
文章前面已经介绍了如何用sklearn模块构建SVM模型,对于线性不可分情况,只需在SVC()函数中指定kernel参数。
mode = svm.SVC (kenel='linear')mode = svm.SVC (kenel='poly',degree=3)mode = svm.SVC (kenel='rbf')
三种分类方式对比: