支持向量机进行光学字符识别_周志华机器学习课后习题(第六章):支持向量机...

dabbe201513211a07dbaca9aa438e282.png

作者 | 我是韩小琦

链接 | https://zhuanlan.zhihu.com/p/49023182

6.1 试证明样本空间中任意点 900267c5-932c-eb11-8da9-e4434bdf6706.svg 到超平面 920267c5-932c-eb11-8da9-e4434bdf6706.svg 的的距离为式 (6.2)。

答:

图中,令A点到超平面(点B)的距离为930267c5-932c-eb11-8da9-e4434bdf6706.svg ,于是 940267c5-932c-eb11-8da9-e4434bdf6706.svg ( 950267c5-932c-eb11-8da9-e4434bdf6706.svg 是 960267c5-932c-eb11-8da9-e4434bdf6706.svg 同向的单位向量, 对于超平面920267c5-932c-eb11-8da9-e4434bdf6706.svg 其垂直方向即 960267c5-932c-eb11-8da9-e4434bdf6706.svg ),对于B点有: 9a0267c5-932c-eb11-8da9-e4434bdf6706.svg ,而 9c0267c5-932c-eb11-8da9-e4434bdf6706.svg ,于是 9f0267c5-932c-eb11-8da9-e4434bdf6706.svg ,可得 a10267c5-932c-eb11-8da9-e4434bdf6706.svg ,这里的 a30267c5-932c-eb11-8da9-e4434bdf6706.svg 即书中 900267c5-932c-eb11-8da9-e4434bdf6706.svg ,即可的式6.2。

781e54c49924dbc540615bc72b1807b0.png

这个问题在吴恩达老师的《机器学习》课程(斯坦福版本CS 229)里面讲解过,有兴趣的可以自己去网易公开课看看,图片截图自该课程课件。

6.2 试使用 LIBSVM,在西瓜数据集 3.0α 上分别用线性核和高斯核训练一个 SVM,并比较其支持向量的差别。

答:

这里没用LIBSVM,用的sklearn中的sklearn.svm.svc,它的实现也是基于libsvm的。

使用不同参数的时候,支持向量是不同的(没有对高斯核中的gamma调参)。由于西瓜数据集3.0a线性不可分,所以使用线性核时,无论惩罚系数多高 ,还是会出现误分类的情况;而使用高斯核时在惩罚系数设置较大时,是可以完全拟合训练数据。所以在惩罚系数设置较小时,两者支持向量都类似,而在惩罚系数较大(支持向量机中,惩罚系数越大,正则化程度越低)时,高斯核的支持向量数目会较少,而线性核的会几乎没有变化。

代码在:han1057578619/MachineLearning_Zhouzhihua_ProblemSets

C = 100时训练情况如下:

高斯核支持向量: [ 8 9 11 12 13 14 16 2 3 4 5 6 7]

a470a1c63a7d555ec7b6fc323bbaa69a.png

----------------------------------------

线性核支持向量: [ 8 9 11 12 13 14 16 2 3 4 5 6 7]

8c9ec5fdcea85a8a13681b1771ef7221.png

C = 10000时训练情况如下:

高斯核支持向量: [11 13 14 1 5 6]

a122e98957e075f9938e72c06d66d5d7.png

----------------------------------------

线性核支持向量: [ 9 11 12 13 14 16 2 3 4 5 6 7]

83a40681332f86e725e8cb460c587099.png

6.3 选择两个 UCI 数据集,分别用线性核和高斯核训练一个 SVM,并与BP 神经网络和 C4.5 决策树进行实验比较。

答:

han1057578619/MachineLearning_Zhouzhihua_ProblemSets

6.4 试讨论线性判别分析与线性核支持向量机在何种条件下等价。

答:

这道题想不出很明确的答案,这仅讨论一下。

有一点很明确的是:在数据线性可分时并不会导致线性判别分析与线性核支持向量机等价。

1a4936534666ab0cd597592ef2dec8e4.png

上图是以iris数据中第0列和第2列数据作为训练集。分别LDA和线性核SVM训练,得到图中两者的决策边界,可以看出在数据线性可分的情况下,两者决策边界还是有很大差别的。如果这里等价理解为两者决策边界相同,即两个模型决策函数是相同的,那么两者决策边界重合时,两者等价的。那么什么时候两者会重叠?

事实上,可以想象到,LDA的决策边界的斜率可以由投影面 960267c5-932c-eb11-8da9-e4434bdf6706.svg 得到,其斜率是垂直于 960267c5-932c-eb11-8da9-e4434bdf6706.svg 的,而截距则可由两类样本的中心点 在 960267c5-932c-eb11-8da9-e4434bdf6706.svg 投影 b30267c5-932c-eb11-8da9-e4434bdf6706.svg 得到,即LDA决策边界通过 b30267c5-932c-eb11-8da9-e4434bdf6706.svg 的中点(公式参考原书p60)。

而线性核SVM的决策边界则由模型参数 b60267c5-932c-eb11-8da9-e4434bdf6706.svg 得到(对应原书式6.12),所以当SVM中的参数 b70267c5-932c-eb11-8da9-e4434bdf6706.svg 和LDA中投影面 b90267c5-932c-eb11-8da9-e4434bdf6706.svg 垂直,且 SVM的b60267c5-932c-eb11-8da9-e4434bdf6706.svg 通过两类样本中心在 b90267c5-932c-eb11-8da9-e4434bdf6706.svg 的投影的中点时,两者等价。只讨论到这里了。

查了很多资料没找到相关信息。感觉LDA和SVM其实没有多大相似度。

ps.这里解答其实就按照结果倒推了一下。貌似都是些废话。

画图代码在:han1057578619/MachineLearning_Zhouzhihua_ProblemSets

代码有点乱。

6.5 试述高斯核 SVM 与 RBF 神经网络之间的联系。

答:

其实这个题目在p145的《休息一会儿》的注释里面已经给出答案了。

RBF神经网络中,将隐藏层神经元个数设置为训练样本数,每个样本设置为一个神经元中心,此时RBF的预测函数和SVM激活函数相同。

个人理解,两个模型还是有挺大差别的。

  • RBF中径向基激活函数中控制方差的参数 bf0267c5-932c-eb11-8da9-e4434bdf6706.svg 是由模型自动习得,而在SVM中是一个可调节的超参。

  • 目标函数、优化方式也不同。

但是如果将RBF中 bf0267c5-932c-eb11-8da9-e4434bdf6706.svg 固定为和SVM一致,最后训练结果应该会比较相似。

以上是个人理解。就不写代码验证了。。。

6.6 试析 SVM 对噪声敏感的原因。

答:

SVM的决策只基于少量的支持向量,若噪音样本出现在支持向量中,容易对决策造成影响,所以SVM对噪音敏感。

6.7 试给出式 (6.52) 的完整 KKT 条件。

答:

6.52式是经过将完整的KKT条件

c10267c5-932c-eb11-8da9-e4434bdf6706.svg ,这里对应着原书式6.47-6.50合并之后的。完整的如下:

c40267c5-932c-eb11-8da9-e4434bdf6706.svg

c50267c5-932c-eb11-8da9-e4434bdf6706.svg

c60267c5-932c-eb11-8da9-e4434bdf6706.svg

c70267c5-932c-eb11-8da9-e4434bdf6706.svg

6.52中其他公式的推导出来的。

6.8 以西瓜数据集 3.0α 的"密度"为输入"含糖率"为输出,试使用LIBSVM 训练一个 SVR。

答:

关于SVR没有理解很深,简单了解了一下。这道题就简单看一下不同参数,训练结果的变换吧。

97cf3f6647a4acc487b9d29f8537ca7e.png
74005a1f96347ce74bfe026c4d15d555.png

直观上看,含糖率和密度无明显关系。所以无论模型参数怎么调,看上去对数据的拟合都不是很好,预测值和真实值还是有较大差异。不过还是可以看出来随着gamma或者C的增大,模型都会趋于更加复杂。

这里代码很简单,还是放上来。

han1057578619/MachineLearning_Zhouzhihua_ProblemSet

6.9 试使用核技巧推广对率回归,产生"核对率回归"。

答:

对于 cd0267c5-932c-eb11-8da9-e4434bdf6706.svg 形式的模型,即线性模型,使用核技巧的关键点在于最优的 cf0267c5-932c-eb11-8da9-e4434bdf6706.svg 可以由训练集的线性组合表示,即 d00267c5-932c-eb11-8da9-e4434bdf6706.svg ,使得模型可表示为 d20267c5-932c-eb11-8da9-e4434bdf6706.svg ,进而使用核函数直接计算数据点在高维空间内积,而不显式的计算数据点从低维到高维的映射。

原命题:事实上对于任何L2正则化的线性模型: d30267c5-932c-eb11-8da9-e4434bdf6706.svg,这里,其最优值都可以表示为 d00267c5-932c-eb11-8da9-e4434bdf6706.svg 。其证明参考下图:(截图自林轩田讲授的《机器学习技法》课程第五章课件)

259a7fbd86be5f40a0cfa06bfce16d59.png

(上图中 d70267c5-932c-eb11-8da9-e4434bdf6706.svg 可以理解为数据点 d80267c5-932c-eb11-8da9-e4434bdf6706.svg 或者 d80267c5-932c-eb11-8da9-e4434bdf6706.svg 在高维空间的映射 db0267c5-932c-eb11-8da9-e4434bdf6706.svg )

上图通过反证法来证明:

将 dc0267c5-932c-eb11-8da9-e4434bdf6706.svg 分解为与 d70267c5-932c-eb11-8da9-e4434bdf6706.svg 空间平行的 df0267c5-932c-eb11-8da9-e4434bdf6706.svg 和垂直的 e00267c5-932c-eb11-8da9-e4434bdf6706.svg ,若 e20267c5-932c-eb11-8da9-e4434bdf6706.svg 则表示 dc0267c5-932c-eb11-8da9-e4434bdf6706.svg 可以表示为 d70267c5-932c-eb11-8da9-e4434bdf6706.svg 的线性组合。

假设 dc0267c5-932c-eb11-8da9-e4434bdf6706.svg 为最优解且 ea0267c5-932c-eb11-8da9-e4434bdf6706.svg 。由于 e00267c5-932c-eb11-8da9-e4434bdf6706.svg 与 d70267c5-932c-eb11-8da9-e4434bdf6706.svg 空间垂直,于是 f00267c5-932c-eb11-8da9-e4434bdf6706.svg , 因此e00267c5-932c-eb11-8da9-e4434bdf6706.svg不会对目标函数中 f30267c5-932c-eb11-8da9-e4434bdf6706.svg 项的大小产生影响,而对于 f40267c5-932c-eb11-8da9-e4434bdf6706.svg ,在 ea0267c5-932c-eb11-8da9-e4434bdf6706.svg 的情况下必定有: f80267c5-932c-eb11-8da9-e4434bdf6706.svg ,显然 df0267c5-932c-eb11-8da9-e4434bdf6706.svg 比 dc0267c5-932c-eb11-8da9-e4434bdf6706.svg “更优”,即 dc0267c5-932c-eb11-8da9-e4434bdf6706.svg 不是最优解。于是原命题得证。

那么对于L2正则化的逻辑回归,其核形式即如下图:

13ae5e161885b776ca3d687544185c01.png

可直接使用梯度下降等优化算法求解上图的目标函数即

题目没要求。就偷个懒不写代码了。

说个题外的。SVM中只有少数支持向量对应的 050367c5-932c-eb11-8da9-e4434bdf6706.svg 非零,所以对于SVM来说,训练完成后只需要储存个别非零的 050367c5-932c-eb11-8da9-e4434bdf6706.svg 和对应数据点即可;而不同于SVM, 核逻辑回归并没有这一性质,需要储存所有训练数据。就这一点来说核逻辑回归并不高效。

6.10* 试设计一个能显著减少 SVM 中支持向量的数目而不显著降低泛化性能的方法。(未完成)

答:

这个应该也是某个论文。最近时间不多,暂时不深究了就。。

6.11 自己编程实现SVM,并在西瓜数据集 3.0αα 测试。

答:

自己加的题目。虽然书上没要求,但还是自己写了一遍。

代码在:

han1057578619/MachineLearning_Zhouzhihua_ProblemSets

其实主要就是把SMO实现了一遍。

参考:

  • 《统计学习方法》

  • 《机器学习实战》

  • 《Sequential Minimal Optimization: A Fast Algorithm for Training Support Vector Machines》

  • 《THE IMPLEMENTATION OF SUPPORT VECTOR MACHINES USING THE SEQUENTIAL MINIMAL OPTIMIZATION ALGORITHM》

写代码的时候参考以上资料。代码主要根据原论文中提供的伪代码和《机器学习实战》的源码写的,《机器学习实战》中给出的代码和原论文有几个地方有差异:

  • 在选择第二个 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg 变量时,原论文给出的方法是1、首先从间隔边界上的支持向量( 100367c5-932c-eb11-8da9-e4434bdf6706.svg )中,找到使得 110367c5-932c-eb11-8da9-e4434bdf6706.svg 最大的 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg 。2、若上面选的 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg 不行,则遍历所有的支持向量。3、还是不行则遍历所有的样本点。4、若所有样本点都不行,则放弃一个变量。关于认定 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg 不行的原则,原论文描述的是:不能使得目标函数有足够下降。实际上在伪代码中是使得 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg 本身有足够下降就认为不行。而《机器学习实战》中代码从更新过的 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg 中选择使得 110367c5-932c-eb11-8da9-e4434bdf6706.svg 最大的 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg作为第二个变量。若不行则直接放弃第一个变量。不知道这一点是改进还是简化。代码中是按照论文的方式实现的

  • 为了选择第二个变量时方便,SMO会将所有支持向量的误差 1a0367c5-932c-eb11-8da9-e4434bdf6706.svg 建立缓存,且在每次更新完 0c0367c5-932c-eb11-8da9-e4434bdf6706.svg之后,都同时更新误差缓存。《机器学习实战》源码中,在给支持向量建立误差缓存时,虽然有更新 1e0367c5-932c-eb11-8da9-e4434bdf6706.svg 的步骤,但只更新了每次更新的两个变量 1f0367c5-932c-eb11-8da9-e4434bdf6706.svg 对应的误差,并且更新之后也没有使用,在选择第二个变量计算 110367c5-932c-eb11-8da9-e4434bdf6706.svg 时,都重新计算了 1a0367c5-932c-eb11-8da9-e4434bdf6706.svg 。在自己实现的时候,这一点也是按照论文来的。

  • 最后一点,在更新 240367c5-932c-eb11-8da9-e4434bdf6706.svg 时,需要计算 260367c5-932c-eb11-8da9-e4434bdf6706.svg (参考统计学习方法 p127 式7.107),在极少数情况下 270367c5-932c-eb11-8da9-e4434bdf6706.svg 会等于零,在原论文中给出了针对这种情况下 240367c5-932c-eb11-8da9-e4434bdf6706.svg 的更新方式,在《机器学习实战》中,这种情况会直接跳过更新。这里代码和《机器学习实战》一致,直接跳过了,这一点其实影响不大。

另外实际上更新误差缓存 1a0367c5-932c-eb11-8da9-e4434bdf6706.svg 有更高效的方法,是在第四个参考文献里面发现的。不过在代码里面没有实现。因为感觉有点复杂。。。有兴趣的可以看看那篇论文,在3.4小节解释了更新误差缓存的方式。

最后自己写的代码在西瓜数据集3.0α上测试了一下,训练后决策边界如下:

79bd0735c72cc7bad761b558ac3331af.png

训练结果和使用sklearn中结果(习题6.2)一致,支持向量也是相同的,决策边界差不多相同,其他数据未测试。不过速度上,sklearn会快很多,测试了一下训练西瓜数据集,自己写的代码需要5e-4秒,而sklearn只需要1e-8。还是有很大差距的。

代码有点乱,这里只为深刻理解一下SMO,也不做工程使用,暂时就不优化了。。以后闲下来再看看。

以上。

系列文章:

1. 周志华机器学习课后习题解析【第二章】

2. 周志华《机器学习》课后习题(第三章):线性模型

3. 周志华《机器学习》课后习题解析(第四章):决策树

4. 周志华《机器学习》课后习题(第五章):神经网络


推荐阅读

(点击标题可跳转阅读)

干货 | 公众号历史文章精选

我的深度学习入门路线

我的机器学习入门路线图

重磅

AI有道年度技术文章电子版PDF来啦!

扫描下方二维码,添加 AI有道小助手微信,可申请入群,并获得2020完整技术文章合集PDF(一定要备注:入群 + 地点 + 学校/公司。例如:入群+上海+复旦。 

77a5c85219d19ff12e0f9f47599ab967.png

长按扫码,申请入群

(添加人数较多,请耐心等待)

最新 AI 干货,我在看 c26f48bfba163d95d84ba736db1c058f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好,以下是第十四章的部分习题python实现: 14.1 腐蚀图像分割 ```python import numpy as np import matplotlib.pyplot as plt from scipy.misc import ascent from scipy.ndimage import grey_erosion img = ascent() # 载入一张灰度图像 selem = np.ones((50,50)) # 定义一个50x50的结构元素 eroded = grey_erosion(img, footprint=selem) # 使用结构元素进行腐蚀操作 # 显示原图和腐蚀后的图像 fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(8, 4)) ax = axes.ravel() ax[0].imshow(img, cmap=plt.cm.gray) ax[0].set_title('Original image') ax[1].imshow(eroded, cmap=plt.cm.gray) ax[1].set_title('Eroded image') plt.show() ``` 14.2 高斯混合模型 ```python import numpy as np from scipy.stats import norm class GMM: def __init__(self, n_components, max_iter=100, tol=1e-6): self.n_components = n_components self.max_iter = max_iter self.tol = tol def fit(self, X): n_samples, n_features = X.shape # 初始化参数 self.weights = np.ones(self.n_components) / self.n_components self.means = X[np.random.choice(n_samples, self.n_components, replace=False)] self.covs = [np.eye(n_features) for _ in range(self.n_components)] for i in range(self.max_iter): # E步,计算每个样本在各分模型下的后验概率 probs = np.zeros((n_samples, self.n_components)) for j in range(self.n_components): probs[:, j] = self.weights[j] * norm.pdf(X, self.means[j], self.covs[j]) probs /= probs.sum(axis=1, keepdims=True) # M步,更新参数 weights_new = probs.mean(axis=0) means_new = np.dot(probs.T, X) / probs.sum(axis=0, keepdims=True).T covs_new = [] for j in range(self.n_components): diff = X - means_new[j] cov_new = np.dot(probs[:, j] * diff.T, diff) / probs[:, j].sum() covs_new.append(cov_new) self.weights = weights_new self.means = means_new self.covs = covs_new # 判断收敛 if np.abs(weights_new - self.weights).max() < self.tol \ and np.abs(means_new - self.means).max() < self.tol \ and np.abs(covs_new - self.covs).max() < self.tol: break def predict(self, X): probs = np.zeros((X.shape[0], self.n_components)) for j in range(self.n_components): probs[:, j] = self.weights[j] * norm.pdf(X, self.means[j], self.covs[j]) return probs.argmax(axis=1) ``` 14.3 隐马尔可夫模型 ```python import numpy as np class HMM: def __init__(self, n_states, n_features): self.n_states = n_states self.n_features = n_features def fit(self, X, max_iter=100, tol=1e-6): n_samples = len(X) # 初始化参数 self.pi = np.ones(self.n_states) / self.n_states self.A = np.ones((self.n_states, self.n_states)) / self.n_states self.B = np.ones((self.n_states, self.n_features)) / self.n_features for i in range(max_iter): # E步,计算前向概率和后向概率 alpha = np.zeros((n_samples, self.n_states)) beta = np.zeros((n_samples, self.n_states)) alpha[0] = self.pi * self.B[:, X[0]] for t in range(1, n_samples): alpha[t] = np.dot(alpha[t-1], self.A) * self.B[:, X[t]] beta[-1] = 1 for t in range(n_samples-2, -1, -1): beta[t] = np.dot(self.A, self.B[:, X[t+1]] * beta[t+1]) gamma = alpha * beta / alpha[-1].sum() # M步,更新参数 self.pi = gamma[0] self.A = np.dot(gamma[:-1].T, self.A * self.B[:, X[1:]] * beta[1:]) / gamma[:-1].sum(axis=0).reshape(-1, 1) self.B = np.zeros((self.n_states, self.n_features)) for k in range(self.n_features): mask = X == k self.B[:, k] = gamma[mask].sum(axis=0) / gamma.sum(axis=0) # 判断收敛 if np.abs(alpha[-1].sum() - 1) < tol: break def predict(self, X): alpha = np.zeros((len(X), self.n_states)) alpha[0] = self.pi * self.B[:, X[0]] for t in range(1, len(X)): alpha[t] = np.dot(alpha[t-1], self.A) * self.B[:, X[t]] return alpha[-1].argmax() ``` 以上是部分习题的python实现,希望对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值