您的位置:首页 > 编程语言 > Python开发

机器学习:支持向量机SVM原理及python实现

2019-03-20 16:02 375 查看

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()方法,模型中可通过设置函数参数调整:

[code]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: 

[code]from sklearn import svm

X=[[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个数据用于测试

[code]import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from 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 = None
clf=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参数。

[code]mode = svm.SVC (kenel='linear')
mode = svm.SVC (kenel='poly',degree=3)
mode = svm.SVC (kenel='rbf')

三种分类方式对比:

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: