vlambda博客
学习文章列表

支持向量机分类及在R中实现

支持向量机分类及在R中实现
支持向量机分类及在R中实现
支持向量机( Support Vector Machine SVM )是一类可用于分类和回归的有监督机器学习模型。
本篇简介 SVM 的分类功能。

SVM分类原理


已知一个数据集包含M个对象N个变量,这些对象可划分为两类别。如果将对象以点绘制在变量空间中,则可获得N维空间。

SVM旨在多维空间中找到一个超平面hyperplane),该平面能够将全部对象分成最优的两类:两类中距离最近的点的间距(margin)尽可能大。这些在间距边界上的点被称为支持向量support vector),它们决定间距,分割的超平面位于间距的中间。

因此在一个N维空间(对应N个变量)中,可获得一个N–1维的最优超平面。如下展示了当变量数为2时的情形,超平面此时是一条直线。当变量数为3时,超平面是一个平面;当变量数N>3时,超平面是N-1维的超平面。

支持向量机分类及在R中实现

该图中,蓝色和红色的点分别代表两类别的对象,数据集通过超平面实现分类。SVM的计算过程可简单概括如下:

1)将M个对象描述在N维变量空间中,SNM中也将对象称为向量(vector),首先使用两个最接近的类间向量计算间距,并获得最大间距(maximum margin);

2)将最大间距分成两部分,获得超平面(hyperplane),超平面是N-1维的;超平面与两个最接近的类间向量等距,这些向量称为支持向量(support vector)。

3)进而通过超平面实现对象分类。

由于此算法完全依赖于支持向量,因此将其命名为支持向量机。

 

不难看出,通过上述过程获得的超平面,实质上代表了一种线性决策面(linear decision surface)。在N维变量空间中的M个对象具有良好的线性可分离特征时,能够实现较好的分类。但实际中,并非所有数据都能适用,有可能数据本身就是非线性的。

如下图(左)所示,该数据集中只有两个变量,因此对于描述在二维变量空间中的对象来说,很难直接通过线性决策面实现划分。

支持向量机分类及在R中实现

在这种情况下,解决方案是将数据投影到更高维的空间。新的维度是虚拟的,称为内核(kernel),计算程序中一般都有默认的内核参数项,也可以在计算过程时手动指定。

例如通过下式投影到高维空间:

支持向量机分类及在R中实现

也可以在计算过程中手动指定内核。

通过引入一个新的维度,使对象在更高维空间中获得线性可分的特征,并应用SVM算法实现类别划分(右)。

 

SVM广泛流行于高维(多元)数据集的分析中,一方面可输出较准确的预测结果,另一方面模型基于较优雅的数学理论。

但是与方法相比,SVM在处理大量样本时的性能较弱。

尽管SVM可以应用于变量数远多于样本数时的情形,但过拟合问题也是经常伴随的。过拟合问题是机器学习方法中普遍存在的缺点,不再多说。

   

R语言执行SVM


接下来通过一个示例,展示 SVM R 中的计算方法。

数据集


威斯康星州乳腺癌数据集,包含699个细胞组织样本,由空心细针在皮下肿瘤组织中抽得。其中458个(65.5%)为良性样本,241个(34.5%)为恶性样本。

#威斯康星州乳腺癌数据集
breast <- read.csv('http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data',na.strings = '?', header = FALSE)
names(breast) <- c('ID', 'clumpThickness', 'sizeUniformity', 'shapeUniformity', 'maginalAdhesion',
    'singleEpithelialCellSize', 'bareNuclei', 'blandChromatin', 'normalNucleoli', 'mitosis', 'class')
 
breast$class <- as.factor(breast$class)
str(breast)

支持向量机分类及在R中实现

数据集中共有11个变量,包括:

ID:样本ID

clumpThickness:肿瘤厚度;

sizeUniformity:细胞大小的均匀性;

shapeUniformity:细胞形状的均匀性;

maginalAdhesion:边际附着力;

singleEpithelialCellSize:单个上皮细胞大小;

bareNuclei:裸核,其中有16个样本中有缺失数据并用“?”表示;

blandChromatin:乏味染色质

normalNucleoli:正常核;

mitosis:有丝分裂;

class:样本类别,2代表良性样本(共458个),4代表为恶性样本(共241个)。

除样本ID和样本类别外,其余9个变量均可视为与判别恶性肿瘤相关的细胞特征,特征以得分为1(最接近良性)至10(最接近病变)之间的整数来表示。

 

任一变量都不能单独作为判别良性或恶性肿瘤的标准,因此接下来综合考虑这9种细胞特征并进行建模,目的是确立一个判断被检者是否患有乳腺癌的分类器模型,实现对恶性肿瘤的准确预测。

#将总数据集分为训练集和测试集
set.seed(123)
select_train <- sample(699, 699*0.7)
 
breast_train <- breast[select_train, ]
breast_test <- breast[-select_train, ]

首先将总数据集分为两部分,70%的样本(行)用作训练集构建预测模型,30%的样本(行)作为测试集评估模型性能。

 

e1071包的SVM


R中,可用于执行SVM的包有很多,如kernlabe1071等。

本篇以e1071包的方法作为展示。

library(e1071)
 
#拟合模型,详情 ?svm
#~. 是使用所有变量的简写,等同于 clumpThickness+sizeUniformity+...+normalNucleoli+mitosis
#推荐使用 scale=TRUE 将变量标准化为均值为 0、标准差为 1,有助于消除方差较大的变量对超平面识别的影响
set.seed(123)
fit.svm <- svm(class~., data = breast_train, scale = TRUE)
fit.svm
 
#细节部分可 names(fit.svm) 后,通过 fit.svm$XXX 等提取查看

支持向量机分类及在R中实现

svm()默认通过径向基函数(Radial Basis FunctionRBF)将对象映射到高维空间,它是一种非线性投影,可以应对类别标签与预测变量间的非线性关系。在用带RBF核的SVM拟合对象时,gammacost是重要的参数。

gamma控制分割超平面的形状,gamma越大通常导致支持向量越多,即意味着训练对象到达范围越广,反之范围越窄。

cost越大意味着模型对误差的惩罚更大,从而将生成一个更复杂的分类边界,对应的训练集中的误差也会更小,但也可能存在过拟合问题,即对新对象的预测误差可能更大;反之分类边界更平滑,但可能会导致欠拟合。

默认情况下,gamma为预测变量个数的倒数,cost1。与直接使用默认值相比,gammacost值的不同组合也可能生成更有效的模型,特别是对于非线性数据集而言。因此实际情况中,通常选择不同的参数多加调试并选择相对更优的组合。

e1071包中也提供了一个方法,可以通过设置参数的候选范围,对每一个参数组合生成一个SVM模型,并输出最佳的组合值。

#tune.svm() 可用于自动确定最佳的 gamma 和 cost 值,详情 ?tune.svm
set.seed(123)
tuned <- tune.svm(class~., data = breast_train, gamma = 10^(-6:1), cost = 10^(-10:10))
tuned

支持向量机分类及在R中实现

训练集的10折交叉验证误差最小的模型给出评估,推荐使用gamma=1e-4cost=10

接下来将上述确定的costgamma值输入至拟合模型中,即手动指定内核。

#本示例给出 gamma=1e-4,cost=10
set.seed(123)
fit.svm <- svm(class~., data = breast_train, scale = TRUE, gamma = 1e-4, cost = 100)
fit.svm
 
#细节部分可 names(fit.svm) 后,通过 fit.svm$XXX 等提取查看


 

将构建好的分类器分类训练集样本,查看判别的样本分类情况。

#训练集自身的预测
#注,支持向量机预测时不允许有缺失值出现,因此使用 na.omit() 去除数据集中的缺失值
pred_train <- predict(fit.svm, na.omit(breast_train))
svm_accuracy <- table(na.omit(breast_train)$class, pred_train, dnn = c('Actual', 'Predicted'))
svm_accuracy

支持向量机分类及在R中实现

分类准确度在(291+173)/(291+173+5+7)≈97.5%,非常可观的。

接下来使用测试集数据,进一步评估分类器性能。

#使用测试集样本进行评估
#同上,支持向量机预测时不允许有缺失值出现,因此使用 na.omit() 去除数据集中的缺失值
pred_test <- predict(fit.svm, na.omit(breast_test))
svm_accuracy <- table(na.omit(breast_test)$class, pred_test, dnn = c('Actual', 'Predicted'))
svm_accuracy

支持向量机分类及在R中实现

对于训练集外的测试样本,分类准确度为(142+57)/(142+57+6+2)≈96.1%,同样是很高的。

   

参考资料


Robert I. Kabacoff. R语言实战(第二版)(王小宁 刘撷芯 黄俊文  译)人民邮电出版社, 2016.

 


支持向量机分类及在R中实现
链接
支持向量机分类及在R中实现