龙猫芭蕉

读万卷书,行万里路

  • 主页
  • 随笔
  • 笔记
所有文章 关于我

龙猫芭蕉

读万卷书,行万里路

  • 主页
  • 随笔
  • 笔记

R语言数据挖掘——支持向量机

2020-03-24
字数统计: 2.5k字   |   阅读时长: 10分

支持向量机是借助最优化方法来解决机器学习问题的新工具,建立在统计学理论的VC维理论和结构风险最小原理基础之上,根据有限样本在模型的复杂性和学习能力之间寻求最佳折中。它在解决小样本、非线性及高维度模式识别中表现出许多优势,并能推广应用到函数拟合等其他机器学习问题中。

1 算法简述

该算法相对于其他算法具有更好的预测准确率,主要是因为它可以将低维线性不可分的空间转换为高维的线性可分空间。思想是利用某些支持向量所构成的“超平面”,将不同类别(如线性可分、近似线性可分和非线性可分)的样本点进行划分。如果样本点是非线性可分,就借助核函数技术,实现样本在核空间下完成线性可分的操作。关于“超平面”该如何构造是一个非常复杂的问题,本学渣表示还需要继续深入学习=.=。

支持向量机是一种努力使得结构风险最小化的算法。在机器学习领域中,所谓风险指的是近似模型与真实模型之间的误差。最直观的想法是使用分类器在样本数据上的分类结果与真实结果之间的差值来表示,这个差值统计上称之为经验风险。另外还有一个置信风险,代表了我们再多大程度上可以信任分类器在未知样本上的分类结果。而结构风险最小化,就是寻求经验风险和置信风险之和最小化。

支持向量机的其他概念还有函数间隔、几何间隔,其中涉及大量的统计知识这里就不写出来了(学渣落泪T_T)。不过这里怎么能跳过最基本的概念——支持向量呢!支持向量其实是指真正发挥作用的数据点,也就是到达决策方程距离最小的点(边界点),就是支持向量机的优化目标——找到一个条线使得离该线最近的点能够最远(即边际最大)——的那个点。如下图:

2 在R中的实现

软件包e1071 主要用于支持向量机的模型构建,核心函数svm()的基本使用格式有两种:
svm(formula, data = NULL, ..., subset, na.action =na.omit, scale = TRUE) 或
svm(x, y = NULL, scale = TRUE, type = NULL, kernel ="radial", degree = 3, gamma = if (is.vector(x)) 1 else 1 / ncol(x) , ..., class.weights = NULL, ...)

根据结果变量的类型,支持向量机模型可以分为分类模型、回归模型或异常检测模型:
如果结果变量为定性变量,则生成分类模型,有C-classification、nu-classification、one-classification三种;
如果结果变量为连续变量,则生成回归模型,有eps-regression、nu-regression两种。

kernel参数有4个可选核函数:线性核函数(linear)、多项式核函数(polynomial)、径向基核函数/高斯核函数(radial basis)以及神经网络核函数(sigmoid)。其中,识别率最高、性能最好的是高斯核函数,其次是多项式核函数,最差的是神经网络核函数。

3 数据集

用的是熟悉的iris数据集:

1
2
3
4
5
6
7
8
9
10
> library(e1071)
> data("iris")
> summary(iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50
Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50
Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500

结果标签setosa、versicolor、virgiuica 是莺尾花属的三种花的类别。本数据采集了这三种花的四项基本特征,分别为:花萼的长度、花萼的宽度、花瓣的长度以及花瓣的宽度。

4 案例应用

4.1 建立模型

下面分别使用两种方法构建模型以及输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#根据既定公式建立模型
> model = svm(Species~., data = iris)

#根据所给的数据集建立模型
> x = iris[, -5]
> y = iris[, 5]
> model = svm(x, y, kernel = 'radial', gamma = if (is.vector(x)) 1 else 1 / ncol(x))
> summary(model)

Call:
svm.default(x = x, y = y, kernel = "radial", gamma = if (is.vector(x)) 1 else 1/ncol(x))

Parameters:
SVM-Type: C-classification
SVM-Kernel: radial
cost: 1

Number of Support Vectors: 51

( 8 22 21 )

Number of Classes: 3

Levels:
setosa versicolor virginica

结果说明该模型的类别为C分类模型,使用的是高斯核函数,cost项目说明本模型确定的约束违反成本为1,且对于该数据,模型找到了51个支持向量,三个类别分别有8、22、21个支持向量。

4.2 预测判别

1
2
3
4
5
6
7
8
9
10
11
12
13
#确认需要进行预测的样本特征矩阵
> x = iris[, 1:4]
> pred = predict(model, x)
> pred[sample(1:150, 8)]
39 143 105 57 3 28 46 32
setosa virginica virginica versicolor setosa setosa setosa setosa
Levels: setosa versicolor virginica
> table(pred, y)
y
pred setosa versicolor virginica
setosa 50 0 0
versicolor 0 48 2
virginica 0 2 48

从混淆矩阵可以看出只有4个样本没有预测正确。

4.3 综合建模

接下来根据3种支持向量分类机和4种核函数,找出最优的参数组合,建立判别结果最优的模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
> attach(iris)
> x = subset(iris, select = -Species)
> y = Species
#确定将要使用的分类方式
> type = c('C-classification', 'nu-classification', 'one-classification')
#确定将要使用的核函数
> kernel = c('linear', 'polynomial', 'radial', 'sigmoid')
#初始化预测结果矩阵
> pred = array(0, dim = c(150, 3, 4))
#初始化模型精准度矩阵
> accuracy = matrix(0, 3, 4)
#为方便模型精度计算,将结果变量数量化为1,2,3
> yy = as.integer(y)
> for (i in 1:3) {
+ for (j in 1:4) {
+ pred[, i, j] = predict(svm(x, y, type = type[i], kernel = kernel[j]), x)
+ #因为三种分类方式的模型预测精度计算方式不同,所以分别计算
+ if (i > 2) accuracy[i, j] = sum(pred[, i, j] != 1)
+ else accuracy[i, j] = sum(pred[, i, j] != yy)
+ }
+ }
#确定模型精度变量的行名和列名
> dimnames(accuracy) = list(type, kernel)
> accuracy
linear polynomial radial sigmoid
C-classification 5 7 4 17
nu-classification 5 14 5 12
one-classification 102 75 76 75

程序中accur代表的是模型预测错误的个数。结果得到12个模型所对应的预测精度,其中可以发现C-classification和高斯核函数结合的模型判别错误最少,仅为4个,因此可以选择该组合方式建立模型,其预测结果如下:
1
2
3
4
5
6
> table(pred[, 1, 3], y)
y
setosa versicolor virginica
1 50 0 0
2 0 48 2
3 0 2 48

4.4 可视化分析

接下来对降维后模型各类别的分布情况和对模型中任意两个特征向量的分布情况进行绘图:

1
2
3
4
5
6
7
8
9
10
11
12
#降维之后的各类别图像
> plot(cmdscale(dist(iris[, -5])),
+ col = c('red', 'blue', 'green')[as.integer(iris[, 5])],
+ pch = c('o', '+')[1:150 %in% model$index + 1])
> legend(1.8, -0.6, c('setosa', 'versicolor', 'virginica'),
+ col = c('red', 'blue', 'green'), lty = 1, cex = 0.5)

#模型中任意两个特征向量的分布情况
> plot(model, iris, Petal.Width ~ Petal.Length, fill = FALSE,
+ symbolPalette = c('red', 'blue', 'green'), svSymbol = '+')
> legend(1, 2.5, c('setosa', 'versicolor', 'virginica'),
+ col = c('red', 'blue', 'green'), lty = 1, cex = 0.5)


左图为对模型数据类别的一个总观察,图中的“+”表示的是支持向量机,“o”表示的是普通样本点。莺尾属中的第一种setosa类别同其他两种区别较大,而剩下的versicolor类别和virginjca类别却相差很小,甚至存在交叉难以区分,这也解释了模型预测中出现的误判问题。右图为在维度Width与Length下各类别分布情况,同样,setosa类别的花瓣同另外两个类别相差较大,而versicolor类别的花瓣同virginica类别的花瓣相差较小。

4.5 优化建模

针对上面得到的存在类别交叉的情况,可以通过改变模型各类别的比重来对模型进行调整。由于类别setosa同其他两个类别的相差较大,所以可以考虑降低类别setosa在模型中的比重,而提高另外两个类别的比重,即适当牺牲类别setosa的精度来提高其他两个类别的精度。这通过svm()函数中的class.weights参数进行调整,该参数所需要的数据必须为向量,并且具有列名。

当各类别比重相等的时候,即模型为最原始的模型,预测效果可见之前的结果;将versicolor类别和virginjca类别的比重扩大100倍和500倍的情况如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#各类别比重相等
> wts = c(1, 1, 1)
> names(wts) = c('setosa', 'versicolor', 'virginica')
> model = svm(x, y, class.weights = wts)

#versicolor类别和virginjca类别的比重扩大100倍
> wts1 = c(1, 100, 100)
> names(wts1) = c('setosa', 'versicolor', 'virginica')
> model1 = svm(x, y, class.weights = wts1)
> pred1 = predict(model1, x)
> table(pred1, y)
y
pred1 setosa versicolor virginica
setosa 50 0 0
versicolor 0 49 1
virginica 0 1 49

#versicolor类别和virginjca类别的比重扩大500倍
> wts2 = c(1, 500, 500)
> names(wts2) = c('setosa', 'versicolor', 'virginica')
> model2 = svm(x, y, class.weights = wts2)
> pred2 = predict(model2, x)
> table(pred2, y)
y
pred2 setosa versicolor virginica
setosa 50 0 0
versicolor 0 50 0
virginica 0 0 50

可以看到,通过调整权重后,支持向量机能够将所有样本全部预测正确。所以在实际构建模型的过程中,在必要的时候可以通过改变各类别样本之间的权重比例来提高模型的预测精度。

  • 本笔记基于黄文和王正林编著的《数据挖掘:R语言实战》整理
赏

谢谢你请我吃糖果

微信
  • 笔记
  • 数据分析与挖掘
  • 机器学习
  • R语言

扫一扫,分享到微信

微信分享二维码
R语言数据挖掘——图形交互界面Rattle的安装与使用
R语言数据挖掘——随机森林
© 2021 龙猫芭蕉
Hexo Theme Yilia by Litten
  • 所有文章
  • 关于我

tag:

  • 随笔
  • 笔记
  • 数据分析与挖掘
  • 机器学习
  • R语言
  • 数据分析
  • SQL
  • Python
  • Hexo
  • ggplot2
  • 读后感
  • 爬虫
  • vlog
  • 生活记录

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 告别2020

    2021-01-01

    #随笔

  • 数模回忆录

    2020-11-26

    #随笔

  • 立冬 | 南国之冬

    2020-11-07

    #vlog#生活记录

  • 请抵达安宁吧

    2020-08-30

    #随笔

  • 爬虫案例 | 基于lxml和Beautiful Soup解析器

    2020-08-29

    #笔记#Python#爬虫

  • 美食记忆 | 广式早茶

    2020-08-22

    #随笔

  • 南沙印象 | 走走停停的周末

    2020-08-16

    #随笔

  • 小向往

    2020-08-08

    #随笔

  • MySQL整理之DQL语言的学习

    2020-05-20

    #笔记#数据分析#SQL

  • MySQL整理

    2020-05-17

    #笔记#数据分析#SQL

  • Pandas整理

    2020-05-01

    #笔记#数据分析#Python

  • NumPy整理

    2020-04-28

    #笔记#数据分析#Python

  • 鸡零狗碎

    2020-04-27

    #随笔

  • 使用stringr处理字符串

    2020-04-20

    #笔记#R语言

  • 函数、判断与迭代

    2020-04-17

    #笔记#R语言

  • ggplot2与数据操作

    2020-04-08

    #笔记#R语言#ggplot2

  • ggplot2学习笔记(2)

    2020-03-31

    #笔记#R语言#ggplot2

  • ggplot2学习笔记(1)

    2020-03-31

    #笔记#R语言#ggplot2

  • 就是这样了

    2020-03-29

    #随笔#读后感

  • R语言数据挖掘——图形交互界面Rattle的安装与使用

    2020-03-26

    #笔记#数据分析与挖掘#机器学习#R语言

  • R语言数据挖掘——支持向量机

    2020-03-24

    #笔记#数据分析与挖掘#机器学习#R语言

  • R语言数据挖掘——随机森林

    2020-03-23

    #笔记#数据分析与挖掘#机器学习#R语言

  • R语言数据挖掘——集成学习

    2020-03-22

    #笔记#数据分析与挖掘#机器学习#R语言

  • R语言数据挖掘——决策树

    2020-03-21

    #笔记#数据分析与挖掘#机器学习#R语言

  • R语言数据挖掘——判别分析

    2020-03-19

    #笔记#数据分析与挖掘#机器学习#R语言

  • R语言数据挖掘——聚类分析

    2020-03-15

    #笔记#数据分析与挖掘#机器学习#R语言

  • R语言数据挖掘——关联分析

    2020-03-14

    #笔记#数据分析与挖掘#机器学习#R语言

  • 我的寒假

    2020-03-07

    #随笔

  • DBSCAN与层次聚类

    2020-02-29

    #笔记#数据分析与挖掘#机器学习#Python

  • Kmeans聚类分析

    2020-02-27

    #笔记#数据分析与挖掘#机器学习#Python

  • 朴素贝叶斯模型

    2020-02-25

    #笔记#数据分析与挖掘#机器学习#Python

  • KNN模型

    2020-02-22

    #笔记#数据分析与挖掘#机器学习#Python

  • 决策树与随机森林

    2020-02-21

    #笔记#数据分析与挖掘#机器学习#Python

  • Logistic回归分类模型

    2020-02-19

    #笔记#数据分析与挖掘#机器学习#Python

  • 岭回归与LASSO回归模型

    2020-02-17

    #笔记#数据分析与挖掘#机器学习#Python

  • 线性回归预测模型

    2020-02-15

    #笔记#数据分析与挖掘#机器学习#Python

  • sql简单语句整理

    2020-02-12

    #笔记#数据分析#SQL

  • 告别2019

    2019-12-31

    #随笔

  • 光影碎片

    2019-12-20

    #随笔

  • 艰辛的hexo之路:gitalk评论插件踩过的坑

    2019-12-11

    #随笔#Hexo

愿一生

温暖纯良
不舍爱与自由