机器学习-SVM

简介:机器学习,小白也能看得懂 , 从理论到实践!!!

视频教学(Youtube & Blibli)

Youtube
Bilibili

什么是机器学习?

  • 机器学习就是wiki
  • 就是利用数学算法,结合大量数据,建立对应数学模型,对未来的数据进行分类(分类-Classification),或者预测趋势(回归-Regression)。
  • 例如:你拥有大量有关房地产价格相关的数据,那么就能利用这些数据建立对应的数学模型进行对未来价格的预测。

什么是SVM?

  • SVM(全称:Support Vector Machine)支持向量机,这只是它的名称,向量就是和我们以前学过的向量一样(下文有介绍),它可以有效解决分类问题(我们只讨论分类问题),何为分类呢?顾名思义,就是把你拥有的数据分成几类。

什么是向量?

  • 向量,顾名思义就是有方向的纯量(标量),纯量呢就是只有大小,没有方向比如5,只有大小,是一个纯量。
    比如有一辆车以每秒10 m/s 的速度超你行驶过来,和以每秒 10m/s 的速度远离你,这车辆的速度虽然一样,但是造成的结果却是大相径庭(撞到你或者远离你),但是如果给这个速度加一个方向,那么你就知道它是以10m/s的速度超哪个方向运动了,这就是向量,有方向的纯量。

Alt text

上图就代表这个有方向的纯量,也就是向量$\vec{ BA }$,它是有方向的,也就是 B$\rightarrow$A。

B 是原点(0,0)
A 坐标(3,2)

所以我们可以写成$\vec{ A }$= (3,2)

支持向量机(SVM)

准备数据

$\vec{A}$= (3,3)
$\vec{B}$= (4,2)
$\vec{C}$= (4,3)
$\vec{D}$= (2,5)
$\vec{E}$= (2,2)
$\vec{F}$= (2,4)
由下图可知,我们想要分类次数据,从数据分析,A,B,C,D,E,F 为一类,G,H,I,J,K为另一类。
$\vec{G}$= (0,1)
$\vec{H}$= (-2,1)
$\vec{I}$= (-2,-1)
$\vec{J}$= (-1,-1)
$\vec{K}$= (1,-1)


Alt text

怎么分类

如下图:
绿圈和红圈是两类数据,这两条线是分类的基准,也就是分类边界,那么那条线比较好一些呢?


Alt text

什么是好?也就是能分的平均,也就是尽量使两类数据对称,尽量使未来的数据也能正确的匹配,泛化力较好(就是使未来要分类的数据也能正确分类),所以那条分类线你应该在脑海里想想出来了吧。

我们要找到最好的一条线去分类这两类数据,那么哪条线是最好的分类线呢?
如下图有红色两条线,红色两条线是两类数据的边界,恰好能分类此数据,但是它的容错性比较低,但是如果我们取两条线中间的那条绿色的线作为分类线,那么对于此类数据,应该是最好的分类线了。


Alt text

专业名称:

那条绿色的线我们叫做超平面(hiperplane)
为什么是超平面,不是超平线呢?因为这只是简单的二维数据,我们到三维,四维,甚至更高维度,所以就称之为超平面了。
支持向量:E,G,K这三个点,支持向量机,有支持向量的点,当然也有不支持的点,这个图只有E,G,K三个点是支持向量的。
间隔:两条红线直接的距离我们称之为间隔。


所以我们以下目标就是要找到那个hiperplane,这是一个数学问题,你要记住以下方法都是来寻找那个超平面的,只不过是利用数学技巧进行优化寻找罢了,目的还是寻找那个hiperplane。

先找二维平面(也就是上图点的分类 线)

利用如上分类点A,B,C,D,E,F,G,H,I,J,K
设训练样本集为T:
T = {($\vec{X}$,Y),$\cdots$}
X 为分类的向量
Y 为分类标记,也就是两个间隔的边界
我们人工手动给现有的数据进行标记,使得我们现有的数据可以分成两类,一类标记为+1,另一类为-1,我们称之为监督学习。

监督学习:

监督学习,就如同我们上面的例子一样,是给现有数据进行人工手动做分类标签,使程序一开始就知道要分类的标签。

非监督学习:

非监督学习,刚好和监督学习相反,就是不给数据做分类标签,让机器自动识别分类类型(不要觉得不可思议,只要我们数据得当,那么结合一定的数学模型,也是容易做到的)


Alt text

$$T = {(\vec{A},YA),(\vec{B},YB),(\vec{C},YC),(\vec{D},YD),(\vec{E},YE),(\vec{F},YF),(\vec{G},YG),(\vec{H},YH),(\vec{I},YI),(\vec{J},YJ),(\vec{K},YK)}$$
$$T = {(\vec{A},1),(\vec{B},1),(\vec{C},1),(\vec{D},1),(\vec{E},1),(\vec{F},1),(\vec{G},-1),(\vec{H},-1),(\vec{I},-1),(\vec{J},-1),(\vec{K},-1)}$$
根据 T 可知,我们要把这个样本集合分成两类就是Y对应的标签(1,-1),如上图
所以我们构造一个方程:
$$\vec{ {W’} }\vec{X_i} + b = y_i$$
如果我们要分类的数据都分别超过他们的边界,那么就可以做很好的分类了。
例如,所有y=-1的数据点都比间隔线小,y=+1的数据都比间隔线大。
所以我们可以做以下方程组:
$$\begin{Bmatrix}
\vec{ {W’} }\vec{X_i} + b \geq +1 , y_i = +1\\
\vec{ {W’} }\vec{ X_i }+ b \leq -1 , y_i = -1\\
\end{Bmatrix}$$
我们把这个方程组合并成一个数学表达式:

$$y_i(\vec{W’X_i} + b) \geq +1 , i = 1,2,3, \cdots ,m$$

因为$y_i$是(+1,-1)正1和负1,如果$y_i$为+1时不用变符号为:

$$\vec{ {W’} }\vec{X_i} + b \geq \frac{ +1 }{ y_i } == +1 $$

如果$y_i$为-1时需要变符号为:

$$\vec{ {W’} }\vec{X_i} + b \leq \frac{ +1 }{ y_i } == -1 $$

以前我们计算方程都是已知参数(W,b)来求x,y。但是现在是已知x,y来求参数(W,b),所以我们的目标是求(W,b)。
现在我们已知A,B,C,D,E,F,G,H,I,J,K这几个点的坐标,那我们怎么反求参数(W,b)呢?我们知道只要间隔最大,那么只要与间隔平行且在间隔中间的那条线就是我们要找的方程了,对吧!
这样就转换了一个方法,我们利用求最大间隔进而来求那个超平面。
我们以前计算的都是纯量的方程,但是如今是向量的方程,其实是一样的,因为以前的X是标量,而如今的X是向量,所以对应的参数($\vec{ W }$)也应该是向量。

怎么计算间隔呢?其实就是一个点到一条线的距离(二维,不过可以类比三维,多维)
$$D_m = \frac{ |\vec{W’x} + b|}{ ||\vec{W}|| }$$


Alt text

因为:$ |\vec{W’x} + b|== 1$
所以:$D = \frac{ 1 }{ ||\vec{W}|| }$
所以:$D_m = \frac{ 2 }{ ||\vec{W}|| }$

所以得到一个约束方程

$$\begin{Bmatrix}
D_m = \frac{ 2 }{ ||\vec{W}|| }\\
y_i(\vec{ {W’} }\vec{X_i} + b) \geq 1 , i = 1,2,3, \cdots ,m
\end{Bmatrix}$$

因为使$\frac{ 2 }{ ||\vec{W}|| }$最大,就是使$||\vec{W}||^{-1}$最大化
就等价于使$||\vec{W}||$最小化

于是得到:
$$\begin{Bmatrix}
D_m = \frac{ ||\vec{W}||^2 }{ 2 } \\
y_i(\vec{ {W’} }\vec{X_i} + b) \geq 1 , i = 1,2,3, \cdots ,m
\end{Bmatrix}$$

为什么不是$D_m = ||\vec{W}||^2$而是$D_m = \frac{ ||\vec{W}||^2 }{ 2 }$
因为本质上都相同,并且在今后的计算方便些

对偶问题

所以我们要求的就成了这个方程
$$\begin{Bmatrix}
D_m = \frac{ ||\vec{W}||^2 }{ 2 } \\
y_i(\vec{ {W’} }\vec{X_i} + b) \geq 1 , i = 1,2,3, \cdots ,m
\end{Bmatrix}$$

利用拉格朗日乘子:
$$L(\vec{W},b,\alpha) = 1/2||\vec{W}||^2 + \sum{\alpha_i(1-y_i(\vec{W}’x_i + b))}$$
令$L(\vec{W},b,\alpha)$对$\vec{W}$和b求偏导数得:

$$\begin{Bmatrix}
\vec{W} = \sum{\alpha y_ix_i}\\
0 = \sum{\alpha y_i}
\end{Bmatrix}$$

最后得出:
$$F(x) = \sum{\alpha_i y_i x_i’x_i + b}$$

代入数据即可求出超平面

线性不可分

我们上面的数据是线性可以分离的,也就是一条线即可分开数据,但是如果遇到下面这种怎么办呢?


Alt text

利用核函数

转换数据到高维度,如图


Alt text

什么是核函数

简单理解就是通过数学手段,把当前数据维度转换到更高维度,如上图的过程

核函数举例

Matlab代码

  • 线性核函数

    $$K(\vec{x_i},\vec{x_j}) = \vec{x_i’}\vec{x_j}$$

  • 高斯核函数

    $$K(\vec{x_i},\vec{x_j}) = (\vec{x_i’}\vec{y_i}^d) $$

  • 拉普拉斯核函数

    $$K(\vec{x_i},\vec{x_j}) = e ^ {- \frac{ ||\vec{x_i} - \vec{x_j}||^2 }{ 2\sigma^2 }} $$

  • Sigmoid核函数

    $$K(\vec{x_i},\vec{x_j}) = tanh(\beta\vec{x_i’}\vec{x_j} + \alpha) $$

    Matlab []
    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
    29
    30
    31
    32
    % Liner
    if (Type == 1)
    ret = x * y;
    end

    % Multil
    if (Type == 2)
    t = 5;
    ret = (x * y) ^ t;
    end

    % Gauss
    if (Type == 3)
    sigm = 1;
    distance = x^2 + y^2;
    ret = exp(-(distance / 2 * sigm ^ 2));
    end

    % Laplace
    if (Type == 4)
    sigm = 5;
    distance = sqrt(x ^ 2 + y ^ 2);
    ret = exp(-(distance / sigm));
    end

    % Sigmoid
    if (Type == 5)
    bt = 1;
    f = pi / 4;
    btNum = bt * (x * y);
    ret = tanh(btNum + f);
    end

    这些函数作用就是扩展维度,进行更好的分类
    如图:离中心近的点(目前在平面上是二维)扩展到三维,就是增加一个Z轴,离中心越近Z就越大,那么就可以做分类了


    Alt text

    蓝色点离中心近,那么经过核函数后,Z轴就越大,反之越小。

Matlab代码

Matlab []
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Main.m

clear;
clc;

% CP is 0,0

% Circle Points Outer Rad 3
% X^2 + Y^2 = 9
% X:3,1,0,-1,-3,-1,0,1,3
% Y:0,sqrt(8),3,sqrt(8),0,-sqrt(8),-3,-sqrt(8),0
X_out = [3,1,0,-1,-3,-1,0,1,3];
Y_out = [0,sqrt(8),3,sqrt(8),0,-sqrt(8),-3,-sqrt(8),0];
Z_out = [KT(X_out(1),Y_out(1)),KT(X_out(2),Y_out(2)),KT(X_out(3),Y_out(3)),KT(X_out(4),Y_out(4)),KT(X_out(5),Y_out(5)),KT(X_out(6),Y_out(6)),KT(X_out(7),Y_out(7)),KT(X_out(8),Y_out(8)),KT(X_out(9),Y_out(9))];
%Z_out = [0,0,0,0,0,0,0,0,0];
% plot(X_out,Y_out,'r*');
scatter3(X_out,Y_out,Z_out,'r*');
hold on;

% Circle Points Inner Rad 1
% X^2 + Y^2 = 4
% X:2,1,0,-1,-2,-1,0,1,2
X_inner = [2,1,0,-1,-2,-1,0,1,2];
Y_inner = [0,sqrt(3),2,sqrt(3),0,-sqrt(3),-2,-sqrt(3),0];
Z_inner = [KT(X_inner(1),Y_inner(1)),KT(X_inner(2),Y_inner(2)),KT(X_inner(3),Y_inner(3)),KT(X_inner(4),Y_inner(4)),KT(X_inner(5),Y_inner(5)),KT(X_inner(6),Y_inner(6)),KT(X_inner(7),Y_inner(7)),KT(X_inner(8),Y_inner(8)),KT(X_inner(9),Y_inner(9))];
% plot(X_inner,Y_inner,'b.');
scatter3(X_inner,Y_inner,Z_inner,'b.');
hold on;

% Test Points
X_t = [1,0.5];
Y_t = [1,(sqrt(3))/2];
Z_t = [KT(X_t(1),Y_t(1)),KT(X_t(2),Y_t(2))];
scatter3(X_t,Y_t,Z_t);
hold on;

TK.m
function [ ret ] = KT( x,y )
% Kernel Trick

% Liner - 1
% Multil - 2
% Gauss - 3
% Laplace - 4
% Sigmoid - 5

Type = 3;

% Liner
if (Type == 1)
ret = x * y;
end

% Multil
if (Type == 2)
t = 5;
ret = (x * y) ^ t;
end

% Gauss
if (Type == 3)
sigm = 1;
distance = x^2 + y^2;
ret = exp(-(distance / 2 * sigm ^ 2));
end

% Laplace
if (Type == 4)
sigm = 5;
distance = sqrt(x ^ 2 + y ^ 2);
ret = exp(-(distance / sigm));
end

% Sigmoid
if (Type == 5)
bt = 1;
f = pi / 4;
btNum = bt * (x * y);
ret = tanh(btNum + f);
end

end

Alt text

这就是核函数的魅力。

### 软间隔


# 实践
### Libsvm
我们使用Libsvm,你也可以使用其他框架例如Tensorflow
它只是一种工具,一个框架,其实你懂得算法流程,自己也可以写这些代码。

#### Libsvm参数说明
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
# -s svm_type : set type of SVM (default 0)
# 0 -- C-SVC (multi-class classification)
# 1 -- nu-SVC (multi-class classification)
# 2 -- one-class SVM
# 3 -- epsilon-SVR (regression)
# 4 -- nu-SVR (regression)
# -t kernel_type : set type of kernel function (default 2)
# 0 -- linear: u'*v 线性核函数
# 1 -- polynomial: (gamma*u'*v + coef0)^degree 多项式核函数
# 2 -- radial basis function: exp(-gamma*|u-v|^2) 高斯核函数
# 3 -- sigmoid: tanh(gamma*u'*v + coef0) sigmoid
# 4 -- precomputed kernel (kernel values in training_set_file)
# -d degree : set degree in kernel function (default 3)
# -g gamma : set gamma in kernel function (default 1/num_features) 核函数gamma参数
# -r coef0 : set coef0 in kernel function (default 0)
# -c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1) 损失参数
# -n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)
# -p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
# -m cachesize : set cache memory size in MB (default 100)
# -e epsilon : set tolerance of termination criterion (default 0.001)
# -h shrinking : whether to use the shrinking heuristics, 0 or 1 (default 1)
# -b probability_estimates : whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)
# -wi weight : set the parameter C of class i to weight*C, for C-SVC (default 1) 对应y标签的权重
# -v n: n-fold cross validation mode 交叉验证
# -q : quiet mode (no outputs)


#### 首先需要处理数据格式(必须按照libsvm格式处理)如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-1 1:3 2:0
-1 1:1 2:2.5
-1 1:0 2:3
-1 1:-1 2:2.5
-1 1:-3 2:0
-1 1:-1 2:-2.5
-1 1:0 2:-3
-1 1:1 2:-2.5
-1 1:3 2:0
1 1:2 2:0
1 1:1 2:1.7
1 1:0 2:2
1 1:-1 2:1.7
1 1:-2 2:0
1 1:-1 2:-1.7
1 1:0 2:-2
1 1:1 2:-1.7
1 1:2 2:0


代码很简单,就是调用Livsvm写好的方法即可:
Python []
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
#!/usr/bin/python
# -*- coding: UTF-8 -*

import sys
import os
sys.path.append(os.getcwd() + r'/libsvmpy/')
from svmutil import *

# 数据目录
linerData = os.getcwd() + r'/data/liner.txt'
circleData = os.getcwd() + r'/data/circle.txt'

# 调用libsvm读取数据(就是我们处理后数据的格式)
Y,X = svm_read_problem(circleData)

# 训练参数,其实就是条件方程的各个参数
arg = '-t 2' # 2 代表高斯核函数

# 训练得到模型m
m = svm_train(Y,X,arg)

# 保存模型m
svm_save_model(r'mod.txt',m)

# 预测结果
# 用的是训练集的数据做预测
svm_predict(Y,X,m)


### 当我们选择不同的核函数时,结果是不同的

> arg = ‘-t 0’

也就是线性核函数


Alt text

arg = ‘-t 2’

也就是高斯核函数


Alt text

选择circleData时候,我们选择

代码地址

结合以前GitHub单独下载文件夹单独下载代码即可

×

谢谢支持

扫码支持
扫码打赏

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 视频教学(Youtube & Blibli)
  2. 2. 什么是机器学习?
  3. 3. 什么是SVM?
  4. 4. 什么是向量?
  5. 5. 支持向量机(SVM)
    1. 5.0.1. 准备数据
    2. 5.0.2. 怎么分类
    3. 5.0.3. 专业名称:
    4. 5.0.4. 先找二维平面(也就是上图点的分类 线)
    5. 5.0.5. 监督学习:
    6. 5.0.6. 非监督学习:
    7. 5.0.7. 所以得到一个约束方程
    8. 5.0.8. 对偶问题
    9. 5.0.9. 线性不可分
    10. 5.0.10. 利用核函数
    11. 5.0.11. 什么是核函数
    12. 5.0.12. 核函数举例
      1. 5.0.12.1. Matlab代码
      2. 5.0.12.2. Matlab代码
  • 6. 代码地址
  • ,