Skip to content

Commit 7a665d8

Browse files
完成 第6章 支持向量机SVM的项目案例
1 parent 2600c81 commit 7a665d8

2 files changed

Lines changed: 21 additions & 24 deletions

File tree

docs/6.支持向量机.md

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
## 支持向量机 场景
1313

14-
* 如果把所有的点看作地雷,那么我们(超平面)得找到最近所有的地雷,并保证我们离它最远。
15-
* 所以:选择D会比B、C分隔的效果要好很多。
14+
* 要给左右两边的点进行分类
15+
* 明显发现:选择D会比B、C分隔的效果要好很多。
1616

1717
![线性可分](/images/6.SVM/SVM_3_linearly-separable.jpg)
1818

@@ -23,7 +23,7 @@
2323

2424
![k_2](/images/6.SVM/k_2.jpg "k_2")
2525

26-
对于上述的苹果和香蕉,我们想象为2中水果类型的炸弹。(保证距离最近的炸弹,距离它们最远)
26+
对于上述的苹果和香蕉,我们想象为2种水果类型的炸弹。(保证距离最近的炸弹,距离它们最远)
2727

2828
1. 寻找最大分类间距
2929
2. 转而通过拉格朗日函数求优化的问题
@@ -74,10 +74,9 @@ This is the simplest kind of SVM (Called an LSVM) Support Vectors are those data
7474
* 类别标签用-1、1,是为了后期方便 \\(lable*(w^Tx+b)\\) 的标识和距离计算;如果 \\(lable*(w^Tx+b)>0\\) 表示预测正确,否则预测错误。
7575
* 现在目标很明确,就是要找到`w``b`,因此我们必须要找到最小间隔的数据点,也就是前面所说的`支持向量`
7676
* 也就说,让最小的距离取最大.(最小的距离:就是最小间隔的数据点;最大:就是最大间距,为了找出最优超平面--最终就是支持向量)
77-
* 怎么理解呢? 例如: 如果把所有的点看作地雷,那么我们(超平面)得找到最近所有的地雷,并保证我们离它最远。
78-
* 目标函数:\\(arg: max\left( min(lable*(w^Tx+b))*\frac{1}{||w||} \right) \\)
77+
* 目标函数:\\(arg: max_{关于w, b} \left( min[lable*(w^Tx+b)]*\frac{1}{||w||} \right) \\)
7978
1. 如果 \\(lable*(w^Tx+b)>0\\) 表示预测正确,也称`函数间隔`\\(||w||\\) 可以理解为归一化,也称`几何间隔`
80-
2.\\(lable*(w^Tx+b)>=1\\), 因为-1~1之间,得到的点是存在误判的可能性,所以要保障min=1,才能更好降低噪音数据影响。
79+
2.\\(lable*(w^Tx+b)>=1\\), 因为0~1之间,得到的点是存在误判的可能性,所以要保障 \\(min[lable*(w^Tx+b)]=1\\),才能更好降低噪音数据影响。
8180
3. 所以本质上是求 \\(arg: max_{关于w, b} \frac{1}{||w||} \\);也就说,我们约束(前提)条件是: \\(lable*(w^Tx+b)=1\\)
8281
* 新的目标函数求解: \\(arg: max_{关于w, b} \frac{1}{||w||} \\)
8382
* => 就是求: \\(arg: min_{关于w, b} ||w|| \\) (求矩阵会比较麻烦,如果x只是 \\(\frac{1}{2}*x^2\\) 的偏导数,那么。。同样是求最小值)
@@ -88,14 +87,14 @@ This is the simplest kind of SVM (Called an LSVM) Support Vectors are those data
8887
* 设g(x,y)=M-φ(x,y) # 临时φ(x,y)表示下文中 \\(label*(w^Tx+b)\\)
8988
* 定义一个新函数: F(x,y,λ)=f(x,y)+λg(x,y)
9089
* a为λ(a>=0),代表要引入的拉格朗日乘子(Lagrange multiplier)
91-
* 那么: \\(L(w,b,\alpha)=\frac{1}{2} * ||w||^2 + \sum_{i=1}^{n} \alpha * [1 - label * (w^Tx+b)]\\)
92-
* 因为:\\(label*(w^Tx+b)>=1, \alpha>=0\\) , 所以 \\(\alpha*[1-label*(w^Tx+b)]<=0\\) , \\(\sum_{i=1}^{n} \alpha * [1-label*(w^Tx+b)]<=0\\)
90+
* 那么: \\(L(w,b,\alpha)=\frac{1}{2} * ||w||^2 + \sum_{i=1}^{n} \alpha_i * [1 - label * (w^Tx+b)]\\)
91+
* 因为:\\(label*(w^Tx+b)>=1, \alpha>=0\\) , 所以 \\(\alpha*[1-label*(w^Tx+b)]<=0\\) , \\(\sum_{i=1}^{n} \alpha_i * [1-label*(w^Tx+b)]<=0\\)
9392
* 相当于求解: \\(max_{关于\alpha} L(w,b,\alpha) = \frac{1}{2} *||w||^2\\)
9493
* 如果求: \\(min_{关于w, b} \frac{1}{2} *||w||^2\\) , 也就是要求: \\(min_{关于w, b} \left( max_{关于\alpha} L(w,b,\alpha)\right)\\)
9594
* 现在转化到对偶问题的求解
9695
* \\(min_{关于w, b} \left(max_{关于\alpha} L(w,b,\alpha) \right) \\) >= \\(max_{关于\alpha} \left(min_{关于w, b}\ L(w,b,\alpha) \right) \\)
9796
* 现在分2步
98-
* 先求: \\(min_{关于w, b} L(w,b,\alpha)=\frac{1}{2} * ||w||^2 + \sum_{i=1}^{n} \alpha * [1 - label * (w^Tx+b)]\\)
97+
* 先求: \\(min_{关于w, b} L(w,b,\alpha)=\frac{1}{2} * ||w||^2 + \sum_{i=1}^{n} \alpha_i * [1 - label * (w^Tx+b)]\\)
9998
* 就是求`L(w,b,a)`关于[w, b]的偏导数, 得到`w和b的值`,并化简为:`L和a的方程`
10099
* 参考: 如果公式推导还是不懂,也可以参考《统计学习方法》李航-P103<学习的对偶算法>
101100
![计算拉格朗日函数的对偶函数](/images/6.SVM/SVM_5_Lagrangemultiplier.png)
@@ -111,9 +110,7 @@ This is the simplest kind of SVM (Called an LSVM) Support Vectors are those data
111110
* 这一结论十分直接,SVM中的主要工作就是要求解 alpha.
112111

113112

114-
### SMO高效优化算法
115-
116-
SMO 是 SVM最流行的一种实现
113+
### SMO 高效优化算法
117114

118115
* SVM有很多种实现,最流行的一种实现是: `序列最小优化(Sequential Minimal Optimization, SMO)算法`
119116
* 下面还会介绍一种称为`核函数(kernel)`的方式将SVM扩展到更多数据集上。
@@ -215,7 +212,7 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
215212
"""smoSimple
216213
217214
Args:
218-
dataMatIn 数据集
215+
dataMatIn 特征集合
219216
classLabels 类别标签
220217
C 松弛变量(常量值),允许有些数据点可以处于分隔面的错误一侧。
221218
控制最大化间隔和保证大部分的函数间隔小于1.0这两个目标的权重。
@@ -247,7 +244,7 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
247244
# print 'alphas=', alphas
248245
# print 'labelMat=', labelMat
249246
# print 'multiply(alphas, labelMat)=', multiply(alphas, labelMat)
250-
# 我们预测的类别 y = w^Tx[i]+b; 其中因为 w = Σ(1~n) a[n]*lable[n]*x[n]
247+
# 我们预测的类别 y[i] = w^Tx[i]+b; 其中因为 w = Σ(1~n) a[n]*lable[n]*x[n]
251248
fXi = float(multiply(alphas, labelMat).T*(dataMatrix*dataMatrix[i, :].T)) + b
252249
# 预测结果与真实结果比对,计算误差Ei
253250
Ei = fXi - float(labelMat[i])
@@ -325,7 +322,7 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
325322
return b, alphas
326323
```
327324

328-
[完整代码地址:SVM简化版应用简化版SMO算法处理小规模数据集](https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-simple.py): <https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-simple.py>
325+
[完整代码地址:SVM简化版应用简化版SMO算法处理小规模数据集](https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-simple.py): <https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-simple.py>
329326

330327
[完整代码地址:SVM完整版,使用完整 Platt SMO算法加速优化,优化点:选择alpha的方式不同](https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-complete_Non-Kernel.py): <https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-complete_Non-Kernel.py>
331328

@@ -340,19 +337,19 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
340337
* 如果觉得特征空间很装逼、很难理解。
341338
* 可以把核函数想象成一个包装器(wrapper)或者是接口(interface),它能将数据从某个很难处理的形式转换成为另一个较容易处理的形式。
342339
* 经过空间转换后:低维需要解决的非线性问题,就变成了高维需要解决的线性问题。
343-
* SVM 优化特别好的地方,在于所有的运算都可以写成内积(inner product: 是指2个向量相乘,得到单个标量 或者 数值);内核替换成核函数的方式被称为`核技巧(kernel trick)`或者`核"变电"(kernel substation)`
340+
* SVM 优化特别好的地方,在于所有的运算都可以写成内积(inner product: 是指2个向量相乘,得到单个标量 或者 数值);内积替换成核函数的方式被称为`核技巧(kernel trick)`或者`核"变电"(kernel substation)`
344341
* 核函数并不仅仅应用于支持向量机,很多其他的机器学习算法也都用到核函数。最流行的核函数:径向基函数(radial basis function)
345342
* 径向基函数的高斯版本,其具体的公式为:
346343

347344
![径向基函数的高斯版本](/images/6.SVM/SVM_6_radial-basis-function.jpg)
348345

349-
### 项目案例: 手写数字识别的优化(无核函数
346+
### 项目案例: 手写数字识别的优化(有核函数
350347

351348
#### 项目概述
352349

353350
```python
354-
你的老板要求:你写的那个手写书别程序非常好,但是它占用内存太大。顾客无法通过无线的方式下载我们的应用。
355-
所以:我们可以考虑使用支持向量机,保留支持向量就行(knn需要保留所有的向量),就可以获得可比的效果
351+
你的老板要求:你写的那个手写识别程序非常好,但是它占用内存太大。顾客无法通过无线的方式下载我们的应用。
352+
所以:我们可以考虑使用支持向量机,保留支持向量就行(knn需要保留所有的向量),就可以获得非常好的效果
356353
```
357354

358355
#### 开发流程
@@ -430,7 +427,7 @@ def loadImages(dirName):
430427

431428
> 分析数据:对图像向量进行目测
432429
433-
> 训练算法:采用两种不同的核函数,并对径向基和函数采用不同的设置来运行SMO算法
430+
> 训练算法:采用两种不同的核函数,并对径向基核函数采用不同的设置来运行SMO算法
434431
435432
```python
436433
def kernelTrans(X, A, kTup): # calc the kernel or transform data to a higher dimensional space
@@ -447,7 +444,7 @@ def kernelTrans(X, A, kTup): # calc the kernel or transform data to a higher di
447444
m, n = shape(X)
448445
K = mat(zeros((m, 1)))
449446
if kTup[0] == 'lin':
450-
# linear kernel: m*n * n*1 = m*1, 求y值
447+
# linear kernel: m*n * n*1 = m*1
451448
K = X * A.T
452449
elif kTup[0] == 'rbf':
453450
for j in range(m):
@@ -550,12 +547,12 @@ def testDigits(kTup=('rbf', 10)):
550547
print("the test error rate is: %f" % (float(errorCount) / m))
551548
```
552549

553-
> 使用算法:一个图像识别的完整应用还需要一些图像处理的只是,这里并不打算深入介绍
550+
> 使用算法:一个图像识别的完整应用还需要一些图像处理的知识,这里并不打算深入介绍
554551
555552
[完整代码地址](https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-complete.py): <https://github.com/apachecn/MachineLearning/blob/master/src/python/6.SVM/svm-complete.py>
556553

557554
* * *
558555

559-
* **作者:[片刻](http://www.apache.wiki/display/~jiangzhonglian) [geekidentity](http://www.apache.wiki/display/~houfachao)**
556+
* **作者:[片刻](http://cwiki.apachecn.org/display/~jiangzhonglian) [geekidentity](http://cwiki.apachecn.org/display/~houfachao)**
560557
* [GitHub地址](https://github.com/apachecn/MachineLearning): <https://github.com/apachecn/MachineLearning>
561558
* **版权声明:欢迎转载学习 => 请标注信息来源于 [ApacheCN](http://www.apachecn.org/)**

src/python/6.SVM/svm-complete.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def kernelTrans(X, A, kTup): # calc the kernel or transform data to a higher di
6161
m, n = shape(X)
6262
K = mat(zeros((m, 1)))
6363
if kTup[0] == 'lin':
64-
# linear kernel: m*n * n*1 = m*1, 求y值
64+
# linear kernel: m*n * n*1 = m*1
6565
K = X * A.T
6666
elif kTup[0] == 'rbf':
6767
for j in range(m):

0 commit comments

Comments
 (0)