vlambda博客
学习文章列表

入门支持向量机(SVM)原来这么简单


在之前的内容k-NN算法中,我们把样本点投影到二维平面上,计算样本点之间的距离,然后找到距离测试点最近的k个邻居,进行投票得出结论。今天我们将接触一个新的算法——支持向量机, (Support Vector Machine, SVM),它将训练样本点投影到二维空间上后(或者n维空间)后,去找一个超平面(hyper-plane),这个超平面将训练样本点很好地分为两类。

很显然,这是一个基于模型(先在训练集上训练,得到模型)的监督学习(训练集都有标签)的常用于二分类的算法。

为什么叫支持向量机?这个超平面是什么?那么下面就开始今天的内容吧。

本文涉及到的内容有:
1、SVM原理
2、SVM实例
3、参数调优——网格搜索

支持向量机(Support Vector Machine,SVM)


一个例子


假设训练集的特征有两列,下图的示意图表示了训练集的点投影到二维空间,两个坐标轴的取值分别表示两个特征的值,蓝色和红色代表两种样本点的类型。

接下来我们想找一个“分界线”把他们分开。


入门支持向量机(SVM)原来这么简单

先画了这条绿的线,好像这条线不太合适,因为它把其中一个蓝色的点错分了。

入门支持向量机(SVM)原来这么简单

接着又重画了一条黄色线,看似这条线很好地将样本点区分开来。但是当测试点加入时:
入门支持向量机(SVM)原来这么简单


原本属于红色类型的点,被错分到了蓝色类型中去。所以这条线产生一些误差,那么有没有最优的那条直线呢?

如下图。
入门支持向量机(SVM)原来这么简单
入门支持向量机(SVM)原来这么简单

这条直线不仅很好地将两类区分开,并且距离直线最近的两个点离直线的距离最大,而上一个图的距离比较小,易产生误差。

所以这条直线就是SVM的在训练集上得到的模型了。

接下来,让我们用更专业的说法来描述一下SVM。

相关知识

概念


支持向量机是一个监督机器学习的算法,它可以用于回归和分类,但是更多地用于分类。

在这个算法中,把每个数据项视为一个n维空间的一个点(n是特征的数量),并且每个特征的值都是一个特定坐标的值。

入门支持向量机(SVM)原来这么简单

特征数量为3时,数据可以视为三维空间中的一个点。

数据是如何分类的


我们通过找到一个能够将两类很好地区分的平面来进行分类,也就是这个算法会输出一个超平面,这个平面可以将新的实例分类。

什么是超平面


在SVM中,对两边的类型的边距都最大化,也就是对每种类型的最近元素的距离都是最大的这条边界,在一维空间是一个点,在二维空间是一条直线,三维空间是一个平面,再高维的就叫做超平面。

什么是支持向量(Support Vector)


一个点就是一个向量。能够决定超平面,也就是决定超平面的参数的数据点,就是支持向量。这些点是两个类别中离超平面最近的点,而距离相对较远的点对超平面的决定没有影响。

应用


SVM在各领域的模式识别问题中有应用,包括人像识别、文本分类 、手写字符识别 、生物信息学等。

实例


  
    
    
  
1import numpy as np
2import matplotlib.pyplot as plt
3import pandas as pd

这里用到的数据依然是之前的汽车公司的用户数据,共有400个样本。本例想要通过age(年龄)和estimatedsalary(评估薪水)来预测用户购买汽车的意向。预测结果将为0或1,0代表不购买,1代表购买。

数据预处理


  
    
    
  
1#数据类型转换
2dataset[['age','estimatedsalary']]=dataset[['age','estimatedsalary']].astype(int)
3#设置特征和标签
4X = dataset.iloc[:, [01]].values
5y = dataset.iloc[:, 3].values
6#划分训练集和测试集,300个为训练集,100个为测试集。
7from sklearn.model_selection import train_test_split
8X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)
9#标准化
10from sklearn.preprocessing import StandardScaler
11sc = StandardScaler()
12X_train = sc.fit_transform(X_train)
13X_test = sc.fit_transform(X_test)

先定义一个SVM的SVC类(Support Vector Classification,SVM的用于分类的算法),核函数设置为linear,即线性函数。

训练模型


  
    
    
  
1from sklearn.svm import SVC
2classifier = SVC(kernel='linear', random_state = 0)
3classifier.fit(X_train, y_train)

用训练好的模型预测测试集结果。

预测


  
    
    
  
1y_pred = classifier.predict(X_test)

接下来用混淆矩阵查看测试结果。

  
    
    
  
1from sklearn.metrics import confusion_matrix
2cm = confusion_matrix(y_test, y_pred)
3cm


入门支持向量机(SVM)原来这么简单

可以看到准确率为0.88


入门支持向量机(SVM)原来这么简单

结果可视化如上图,测试集被这条线性边界分为两类。


超参数介绍


默认参数:

入门支持向量机(SVM)原来这么简单


常涉及到的参数有下面三个:


正则化系数,C

C比较大时,如果一个超平面能够正确的将所有训练点分类,那么优化时将会选择这个超平面,容忍错误的程度低(这可能导致过拟合——被一些异常点影响,导致泛化能力低)。相反,C比较小时,将会在寻找更大边距中有着更好地效果,即使这个超平面错误地将更多点分类,也就是容忍错误的程度会更高,可以一定程度上避免过拟合。
(过拟合、泛化能力的名词解释见本文末尾)

kernel核函数

取值为linear,则是线性SVM,超平面确定是使用一些线性代数;rbf:可以将数据映射到更高维的空间里来确定超平面,可用于线性不可分的情况。

Gamma γ

γ被定义为是一个单个训练集可以产生影响的距离是多远。γ较小,离可能的分界线比较远的点也参与了超平面的计算,当γ比较大,则只有离可能的超平面比较近的点参与计算。

之前我们简单定义的一个SVC模型在测试集上的准确率为0.88,现在我们要搜索超参数空间来为分类器模型寻找最优模型的超参数,提升准确率。

调参——网格搜索


网格搜索最优模型


网格搜索会遍历每一种超参数的组合的模型,并且验证模型,得到分数。最后可以得到最高分数的模型、超参数

  
    
    
  
1from sklearn.model_selection import GridSearchCV,KFold, cross_val_score
2#设置超参数空间,设置每个超参数可能的取值。
3parameters={'kernel':('rbf','linear'),'C':[0.1,1,5,10],'gamma':[1,0.10.010.001]}
4kfold = KFold(n_splits=10,random_state=0# 10折交叉验证,一种验证模型的方法
5classifier = SVC()
6#定义网格搜索对象,括号里的参数为分类器、超参数空间、验证模型的方法。
7clf = GridSearchCV(classifier,parameters,cv=kfold)
8clf.fit(X_train, y_train)
9print('最优模型对象',clf.best_estimator_)
10print('最优模型分数',clf.best_score_)
11print('最优模型参数',clf.best_params_)


入门支持向量机(SVM)原来这么简单


预测结果并生成混淆矩阵


  
    
    
  
1from sklearn.metrics import confusion_matrix
2y_pred = clf.predict(X_test)
3
4cm = confusion_matrix(y_test, y_pred)
5cm


入门支持向量机(SVM)原来这么简单

模型在测试集上的准确率提升至95%。


入门支持向量机(SVM)原来这么简单

在此数据集上分数较高的模型采用rbf核函数,测试集的分类如上图所示。


知识补充


线性不可分情况


可以看到上图的超平面变为非线性。这里补充一下,当两类数据不是线性可分的时候,SVM如何处理。
例如,一些数据点分布如下。
入门支持向量机(SVM)原来这么简单

此时不能用简单的线性边界来区分两类。

接下来我们增加一维特征z,并且使

入门支持向量机(SVM)原来这么简单

再投影到三维空间上去。


入门支持向量机(SVM)原来这么简单


可以看到,现在可以将两类线性分割了。


入门支持向量机(SVM)原来这么简单

假设此时这条线性边界为z=4,那么也就是返回到二维空间上的入门支持向量机(SVM)原来这么简单


入门支持向量机(SVM)原来这么简单


我们得到这个圆为决策边界。

过拟合与欠拟合


入门支持向量机(SVM)原来这么简单


如上图所示,左面的模型想找到一条通过数据的直线。但这样的模型没有足够的灵活性来适应数据的所有特征,这样的模型是欠拟合,也称这种模型有很高的偏差。模型没有很好地适应训练集,这就意味着这个模型对于训练数据和测试集都不是一个好的预测器。

右边的模型使高次多项式穿过数据。这个模型几乎完美地穿过了所有样本,适应了数据的所有特征。这样的模型被称为过拟合:也就是,它有太多的灵活性以至于该模型最终解释了随机错误以及基础数据分布。另一种说法是模型有很高的方差。它很好的适应训练数据,但是对预测没见过的数据效果很差。

泛化能力


机器学习的目标是使学得的模型能很好地适用于"新样本",而不是仅仅在训练样本上工作得很好。学得模型适用于新样本的能力,称为"泛化" (generalization) 能力。


参考资料:

https://github.com/Avik-Jain/100-Days-Of-ML-Code

百度百科,支持向量机

机器学习—周志华



精彩内容回顾:






编辑:Sunam




在疫情防控依旧严峻的形势下,全国高校延期开学,高校师生停课不停学。AI靶场将向全国高校、教师、学生免费提供实战化数据分析环境及多样化优质课程等资源。



抗击疫情
我们一直都在
武汉加油!
中国加油!