视频教学(Youtube & Blibli)
什么是机器学习?
- 机器学习就是wiki
- 就是利用数学算法,结合大量数据,建立对应数学模型,对未来的数据进行分类(分类-Classification),或者预测趋势(回归-Regression)。
- 例如:你拥有大量有关房地产价格相关的数据,那么就能利用这些数据建立对应的数学模型进行对未来价格的预测。
什么是SVM?
- SVM(全称:Support Vector Machine)支持向量机,这只是它的名称,向量就是和我们以前学过的向量一样(下文有介绍),它可以有效解决分类问题(我们只讨论分类问题),何为分类呢?顾名思义,就是把你拥有的数据分成几类。
什么是向量?
- 向量,顾名思义就是有方向的纯量(标量),纯量呢就是只有大小,没有方向比如5,只有大小,是一个纯量。
比如有一辆车以每秒10 m/s 的速度超你行驶过来,和以每秒 10m/s 的速度远离你,这车辆的速度虽然一样,但是造成的结果却是大相径庭(撞到你或者远离你),但是如果给这个速度加一个方向,那么你就知道它是以10m/s的速度超哪个方向运动了,这就是向量,有方向的纯量。

上图就代表这个有方向的纯量,也就是向量$\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)

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

什么是好?也就是能分的平均,也就是尽量使两类数据对称,尽量使未来的数据也能正确的匹配,泛化力较好(就是使未来要分类的数据也能正确分类),所以那条分类线你应该在脑海里想想出来了吧。
我们要找到最好的一条线去分类这两类数据,那么哪条线是最好的分类线呢?
如下图有红色两条线,红色两条线是两类数据的边界,恰好能分类此数据,但是它的容错性比较低,但是如果我们取两条线中间的那条绿色的线作为分类线,那么对于此类数据,应该是最好的分类线了。

专业名称:
那条绿色的线我们叫做超平面(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,我们称之为监督学习。
监督学习:
监督学习,就如同我们上面的例子一样,是给现有数据进行人工手动做分类标签,使程序一开始就知道要分类的标签。
非监督学习:
非监督学习,刚好和监督学习相反,就是不给数据做分类标签,让机器自动识别分类类型(不要觉得不可思议,只要我们数据得当,那么结合一定的数学模型,也是容易做到的)

$$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}|| }$$

因为:$ |\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}$$
代入数据即可求出超平面
线性不可分
我们上面的数据是线性可以分离的,也就是一条线即可分开数据,但是如果遇到下面这种怎么办呢?

利用核函数
转换数据到高维度,如图

什么是核函数
简单理解就是通过数学手段,把当前数据维度转换到更高维度,如上图的过程
核函数举例
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就越大,那么就可以做分类了
蓝色点离中心近,那么经过核函数后,Z轴就越大,反之越小。
Matlab代码
1 | Main.m |

这就是核函数的魅力。
### 软间隔
# 实践
### Libsvm
我们使用Libsvm,你也可以使用其他框架例如Tensorflow。
它只是一种工具,一个框架,其实你懂得算法流程,自己也可以写这些代码。
#### Libsvm参数说明
1 | # -s svm_type : set type of SVM (default 0) |
#### 首先需要处理数据格式(必须按照libsvm格式处理)如下:
1 | -1 1:3 2:0 |
代码很简单,就是调用Livsvm写好的方法即可:
1 | #!/usr/bin/python |
### 当我们选择不同的核函数时,结果是不同的
> arg = ‘-t 0’
也就是线性核函数

arg = ‘-t 2’
也就是高斯核函数

选择circleData时候,我们选择
代码地址
结合以前GitHub单独下载文件夹单独下载代码即可