@Frankchen
2015-12-21T02:21:30.000000Z
字数 64802
阅读 2736
机器学习
--
之前我们介绍过PLA算法,即在线性可分的数据中,找到一条线,能够区分开正负样本.但是PLA的解具有随机性的特点,不同的解具有对噪声不同的容忍度,即点向分类超平面扩展的区域大小对应对于噪声的容忍度。这个边界越大,代表对噪声的容忍度也越大,而从边界线的角度来讲,即从边界线向两侧延伸直到遇到点的这个所谓的“垫子”——我们称之为margin,margin越大,也代表此分类超平面具有最大的鲁棒性,对噪声的容忍度最强。
线性可分支持向量机:
给定线性可分训练数据集,通过间隔最大化或等价求解相应的凸二次规划问题学习得到的分离超平面为
有了linear SVM的定义和要解决的问题之后,我们试图用数学语言来对其进行描述。我们先来看点到分离超平面的距离:
假设分离超平面外有点,其对分离超平面投影和到超平面距离分别为和,超平面法向量为,则
上面得到的问题形式和二次规划QP一致,所以可以使用二次规划的方法求解。二次规划的一般形式如下:
相比较PLA的平面,linear hard SVM得到的平面结果更苛刻,由于有"厚垫子",linear hard SVM不能shatter任意3个inputs,这说明有更少的dichotomie,更小的VC维度,也就有更好的泛化效果。同时,如果使用特征转换,可以使linear hard SVM进行一些更精细的分类。
Linear hard SVM的解法中需要训练数据线性可分,然后通过缩放平面和等价转换,将原始问题转成QP问题求解。数据线性可分在实际情况中很难出现,所以linear hard SVM的应用价值比较有限。同时,在特征转换时,将原始数据映射到其他空间的计算无法省略。接下来课程中,会使用一些方法解决这两个问题,。
上一篇文章总结了linear hard SVM,解法很直观,直接从SVM的定义出发,经过等价变换,转成QP问题求解。这一讲,从另一个角度描述hard SVM的解法,不那么直观,但是可以避免feature转换时的数据计算,这样就可以利用一些很高维度(甚至是无限维度)的feature转换,得到一些更精细的解。
上一节我们讲到SVM问题的定义,如下:
这是一个线性约束问题,不方便优化,是否有一种方法可以将线性约束放到优化问题本身,这样就可以无拘无束的优化,而不用考虑线性约束了。拉格朗日提供了一种方法,可以达到这个目的,称之为拉格朗日乘子式,形式如下(式中,右边的是约束条件):
上面的问题中先max后min的形式不方便求解,不过可以通过一番变化,导出max min的形式,这样就可以从内到外,先计算里面的min,然后计算外面的max。这种变化叫对偶变化。
首先,对于一个固定的有:
而SVM问题满足上述条件,即存在解对于等式两边都是最优解,即我们现在可以通过解相对简单的对偶问题来间接求解原始问题。
经过之前的对偶变换,我们可以得到:
现在对式子做几步变换,首先通过整体取负号的方式转化为min,接着把w代入,并将其他的约束条件写下:
通过上面的计算,其实最后是的线性组合,同样,PLA中的也是的线性组合,只是SVM利用支持向量求解线性组合,PLA使用错误的向量求解。同理,逻辑回归、线性回归也有类似规律,这种现象c被称为"w represented by data"。
本节使用对偶问题,从另外一个侧面求解了SVM,并且数学推导相对复杂,计算量也增加了许多,因为需要求解一个N*N维度的矩阵Q。但是,为什么要做这些事情呢,hard linear SVM要简单许多呢?其实换成对偶问题是为了利用kernel做铺垫,改kernel可以将维度转化的计算省略,从而可以计算很复杂的转化。
标签(空格分隔): 机器学习
上一次我们已经阐述了SVM的最佳解可以通过对偶问题来求得,而最终就是为了应用核技巧在其之上。
核函数:设是输入空间,又称为特征空间,如果存在一个从到的映射:
核技巧的思想是,在学习与预测中只定义核函数,而不显式地定义映射函数。通常,直接计算比较容易,而通过计算和计算并不容易。而值得注意是,是输入空间到特征空间h的映射,特征空间一般是高维的甚至是无穷维的(维度爆炸)。Kernel的本质是将向量feature转换与点积运算合并后的运算。
常见kernel有线性、多项式线性高斯,各有利弊。
线性kernel
不做feature转换,直接使用。不需要使用对偶技巧,直接使用linear hard SVM解。
优点:计算效率高;结果解释性好。
缺点:需要数据线性可分
优点:相比线性kernel,对数据要求没有那么严格
缺点:需要选择的系数较多;Q太大会超出一些计算机的精度,一般Q<=3。
有些资料也称为RBF(Radial Base Function),一般形式为:
优点:调试的系数较少;比线性和多项式更强大,几乎可以适应所有数据;不容易出现计算精度问题
缺点:无线维度无法解释;太强大,容易过拟合;计算开销大。
核函数是SVM画龙点睛之笔,真的很佩服发现kernel的科学家。在实际使用SVM的过程中,很大一部分精力可能就是选择kernel和相关系数。Kernel还可以自定义,但是需要满足一些条件,具体可以参考讲义相关部分。
之前所讨论的SVM都是非常严格的hard版本,必须要求每个点都被正确的区分开。但是,实际情况时很少出现这种情况的,因为噪声数据时无法避免的。所以,需要在Hard-Margin SVM上添加容错机制,使得可以容忍少量噪声数据。
软化SVM的思路类似正规化,在目标函数添加错误累加项,然后加一个系数,控制对错误的容忍度,并且在约束中添加错误容忍度的约束,形式如下:
现在,将上面软化后的SVM问题进行对偶转化和简化,得到的结果和之前hard版本十分类似,好像遇到了老熟人:
α仍然可以使用QP方法计算得到,b的求解也是通过complementary slackness,但是在求解b的过程,可以将向量分为三类,很有参考意义,可用于数据分析。
首先看看complementary slackness条件:
对于Gaussian SVM的参数通常通过validation来选择。而通过cross validation优化过的问题在于它优化的只是一个upper bound,于是通常被用于初步的检验。
我们现在来讲Kernel Logistic Regression,也就是把Kernel的技巧融合到逻辑回归里面。首先我们对比一下Hard-Marin Dual SVM和Soft-Margin Dual:
我们定义线性模型中的线性得分:
可以比较PLA、SVM和Logistic Regression的Error Function:
从图像上可以看出,和的曲线非常相似。而对比我们现在接触过的二元分类线性模型,发现SVM和LogReg在以优化的优点,以及都是分部的宽松上限的缺点上来看,SVM和LogReg是很相似的。
接下来我们讨论用Soft-Margin SVM用于LogReg的可能性。不管是把SVM的结果直接传到s函数当成LogReg还是把SVM的结果当做LogReg的初值,都是有一些不足。
另外一种想法是,把SVM的结果再对应加上两个自由度再做LogReg,这样能充分发挥两者的优点:
上面介绍的方法实际上并不是在空间做LogReg,只是把SVM在空间里面求解,再在空间用和微调,这只是一种近似解。
如果我们真的想在空间做LogReg,这其中的关键在于的最优解是否能被线性表示。而这里我们有个结论就是任何L2-regularized linear model的最优解都可以被线性表示。这个结论可以用反证法证明。
于是我们的问题变为L2-regularized logistic regression:
上次我们讲到Representer Theorem,也就是对于任何L2-regularized线性模型:
如果把Kernel Ridge Regression用于分类,有个特别的名称叫做least-squares SVM (LSSVM)。 用同样的资料分别跑soft-margin Gaussian SVM和Gaussian LSSVM的结果,可以看出后者的SV的数量非常多,这是由于矩阵的不稀疏造成的,这导致LSSVM在预测时的计算量过大。
那么我们如何解决矩阵不稀疏的问题呢?我们提出一种叫做Tube Regression的方法,核心思想是我们在分类超平面两侧造出两个类似“隧道”的分界面,样本点在隧道内我们认为这是小错误,忽略不计,如果在隧道外才算是错误,而错误的大小以与隧道的距离来计算。也就是:
如何把上面的问题转化为对偶问题呢?当然是拉格朗日乘子了,只是这里需要两个乘子,分别是。接下来通过与之前SVM里面讲的几乎完全一样,利用KKT条件得到:
这里回顾我们之前讲过的Kernel模型。我们从开始到现在学了三种基本的线性模型,分别是PLA/pocket,linear ridge
regression和regularized logistic regression。而之前我么也讲过linear soft-margin SVM,也适用于解决线性分类问题。linear SVR,也是解决线性分类问题的一种选择。这些都是线性的模型,而我们也讲过,对于这些线性模型,如果我们加入regularization的部分,都可以转化为可以使用Kernel trick的模型,如linear soft-margin SVM延伸到SVM对偶问题,linear SVR延伸到SVR的对偶问题,而linear ridge regression也可以转化为kernel ridge regression。而regularized logistic regression也可以推导转化为kernel logistic regression,其中也有另外的一种两阶段训练的probabilistic SVM。
在实际使用中,PLA/pocket和linear SVR因为对比其他模型没有什么显著地优势,使用的较少。那么kernel ridge
regression和kernel logistic由于的不稀疏而导致的预测时候计算的困难而也是实际中不常被使用。
剩余的这些模型,如kernel ridge regression、kernel logistic regression、SVM、SVR、probabilistic SVM等等,都是实际中很常用的模型,Kernel给这些模型带来几乎是无限的power的表现力的同时,我们同时也要注意Kernel也不是万能的,过大的powerful也会带来overfit听的危险,于是实际使用当中我要谨慎小心选择参数。
假设有T个朋友告诉你将来几天股市的假设,那我们到底选哪一个人的模型好呢?
- 你可以选择你最信任的朋友的假设,或者说选择你认为炒股最厉害的朋友;
- 你可以综合所有的朋友的建议,每个人投一票;
- 你可以选择一些朋友的票数占的更多,一些朋友的票数更少,即权重不一样;
- 你可以在不同的条件下听取不同朋友的意见;
后面三个模型对应的数学表达式分分别为:
所以我们得到的混合模型(AggregationModel):把全部的假设进行混合或者结合,这样可以得出更好的假设。于是我们就得出了Aggregation Model(混合模型)的概念。
为什么Aggregation(混合模型)可以工作?他有什么好处呢?作者用了一个二元分类的例子证明了混合模型确实要比单个模型做的更好。
如果单个模型都不强,那我们在这些单个模型当中选择一个最好的也没用,但是我们把这些当模型组合起来的话就会得到很好的效果。Aggregation在这里既当油门又当刹车。
1)可以把不同的weakhypotheses混合,把模型变得更更好。就有点像feature transform
2)选择最好的Hypotheses,就像正则化。
1.Uniform Blending(Voting) for Classification(均匀混合(投票)的分类)
混合模型分类的数学表示是:
我们根据第一小节,我们知道linear Blending的一般表达式:
为了设计出不同的h, 我们通常会使用下面这几种方法:
1)diversity by different models # 不同模型
2)diversity by different parameters # 不同参数
3)diversity by algorithmic randomness # 算法随机性
4)diversity by data randomness # 数据随机性,这个分为两种:一种是随机进行划分训练和CV,另外一种则是从已有数据利用重新抽样的方式生成新的数据集合(bootstrapping).
bootstrapping操作是这样的:在大小为N的数据集合上,随机并且可以有放回地取N'次,取出的数据集合大小为N'。 bagging是利用bootstrapping重新生成一些新的数据集合,在这些新的数据集合上训练出H,然后将这些h平均组合起来。
bagging:bootstrap aggregating的缩写。让该学习算法训练多轮,每轮的训练集由从初始的训练集中随机取出的n个训练样本组成,某个初始训练样本在某轮训练集中可以出现多次或根本不出现,训练之后可得到一个预测函数序列 ,最终的预测函数H对分类问题采用投票方式,对回归问题采用简单平均方法对新示例进行判别。
在上一讲当中我们知道:为了设计出不同的h,我们通常的做法是diversity by data randomness,即bootstrapping方法。操作是这样的:在大小为N的数据集合上,随机并且可以有放回地取N'次,取出的数据集合大小为N'。这样,数据就更多样化,实例证明,得到的效果就会更好。
那在本小节要解决的只有一个问题:how to re-weight for more diverse hypotheses?请看下面的推导过程:
令:\epsilon _t=\frac{\sum_{n=1}^{N}u_n^{(t+1)}[\![y_n\neq g_t(x_n) ]\!]}{\sum_{n=1}^{N}u_n^{(t+1)}}
- obtain g_t by \mathcal{A}\left(\mathcal{D} ,u_n^{(t)}\right),
where \mathcal{A} tries to minimize u_n^{(t)} )-weighted 0/1 error- update u_n^{(t)} to u_n^{(t+1)} by
\text{incorrect:}\quad \leftarrow \quad \text{incorrect}\quad\cdot \quad\beta
其中 \beta = \sqrt \frac{1-\epsilon _t}{\epsilon _t}
- 计算 \alpha _t=\ln \beta
- 返回:G(X)=sign\left( \sum_{t=1}^{T}\alpha _t*g_t(x)\right)
这就是整个算法的过程!
上面这个就是决策树。那用语言来定义决策树的话就是,林老师是这样定义的:a traditional learning model that realizes conditional aggregation。
一颗大树可以分为很多小树(sub-tree),分为树的节点(node),树的叶子(leaf)。节点在这里就是条件 q_t(x),如上图的 has a date?deadline? 叶子在这里就是 g_t(x), 那在上面这棵树是常数。所以整棵树的数学表达式为:G(x)=\sum_{t=1}^{T}q_t(x)*g_t(x)
- G(x):full tree hypothesis
- b(x):branching criteria
- G_c(x):sub-tree hypothesis at the c-th branch
首先,让我们来看一下一个基本的决策树算法的具体流程:
G(x)=\sum_{c=1}^{C}[\![ b(x=c)]\!]G_c(x)
首先,对随机森林做总的概括:随机森林由许多的决策树组成,因为这些决策树的形成采用了随机的方法,因此也叫做随机决策树。随机森林中的树之间是没有关联的。当测试数据进入随机森林时,其实就是让每一颗决策树进行分类,最后取所有决策树中分类结果最多的那类为最终的结果。因此随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
随机森林由决策树组成,决策树实际上是将空间用超平面进行划分的一种方法,每次分割的时候,都将当前的空间一分为二。
下面具体介绍过程:其实随机森林就是用bagging的方式把一堆 decision tree 合起来,即,
\left( I\right) 每一轮用bootstrapping的方式得到不同的资料,\mathcal{D}\rightarrow \mathop{\mathcal{D_t}}^\sim
\left( II\right) 把这些得到的资料送到每一棵树(decision tree),经过树之后,我们会得到 g_t
\left( III\right) 再把每一棵树的 g_t 进行投票,即返回到bagging的方法。得到G=\text{Uniform}\left(\{g_t\} \right)
- randomly sample d' features from x
技术上来说,我们做的事情是从100个维度里面随机选择10个维度,也就是做了一个投影的动作,所以我们会得到 d' 个特征的子空间,也即:
- \mathcal{X}\in R^d, 转换的子空间 \mathcal{Z}\in R^{d'};
每一次做branch的时候,都做一次这样的投影,那么,随机森林的等式又可以进一步表示为:\text{R F}=\text{bagging}+\text{random-subspace C&RT }
让我们再次回顾 bagging 和 bootstrapping 的过程,就像上面的这个表格,例如,我们在做 g_1 的时候,我们选到了第一个资料和第 N 个资料,而其他的资料没有被选到。上面的打星号的就是没有被选到的资料,我们称这些没有被选到的资料为 out-of-bag(OOB).
那有多少资料没有被选到呢?如果 N 足够大的话,我们可以这样计算:\left( 1-\frac{1}{N}\right)^N=\frac{1}{\left( \frac{N}{N-1}\right)^N}=\frac{1}{\left(1+ \frac{1}{N-1}\right)^N}\approx \frac{1}{e}
根据上面这个表格,就是我们所学过的 validation ,蓝色的资料我们用来训练,红色的资料我们用来验证,那我们可以从这里得到的启发是:我们可以用 OOB 资料来做验证,那我们用 OOB 资料来验证 g_t 还是 G 呢?当然是 G 。根据我们在基石课程当中所学的知识,我们可以求得:E_{oob}(G)=\frac{1}{N}\sum_{n=1}^{N}\text{err}(y_n,G_n^-(x_n))
在我们进行特征选择的时候,在10000个维度当中,可能相关的就300个,所以我们要去掉一些冗余的资料,去掉我们不需要的特征或杂序。
但是我们应该怎么选呢?可能在选择的过程当中,你可能从10000选300没做好的话,就可能会发生overfit 。其实我们之前在选择 b(x) 的时候,已经在做选择,即到底切哪里。
我们可以给每一个 feature 打一个分数,然后分数从高到低排序:\text{score}=W^TX=\sum_{i=1}^{d}w^Tx
这一小节就是把 Decision Tree 搭配 AdaBoost,我们在前面都学过,只是把它们结合起来。结合后,就成了有权重的树,那我们可以不改变原来的演算法,只是在抽取资料的过程当中要适当改变,如果权重是3,那代表我们取到3份,我们可以根据权重进行sample。然后送到 decision tree算法当中,得到 g_t。
第二步就是 g_t 得到多少票,我们在学习 adaboost 过程当中知道,权重是:
\alpha _t =\ln \sqrt \frac{1-\epsilon _t}{\epsilon _t}
上面是 AdaBoost 权重迭代的过程,我们在第8讲当中有介绍,如果是正确的话,就是 y_n 和 g_t 是同号,所以相乘为+1,错误则相反。所以上面的式子会成立。把连乘转化为连加:u_n^{(T+1)}=u_n^{(1)}\cdot \prod_{t=1}^{T}exp\left(-y_n\alpha _t g_t(x_n) \right)=\frac{1}{N}\cdot exp\left(-y_n\sum_{t=1}^{T}\alpha _t g_t(x_n) \right)
也即,让下面这个求和越来越小:\sum_{n=1}^{N}u_n^{(T+1)}=\frac{1}{N}\sum_{n=1}^{N}exp\left(-y_n\sum_{t=1}^{T}\alpha _t g_t(x_n) \right)
经过上面的泰勒展开以及化简,第二个等式和第一个等式长得差不多,所以AdaBoost的错误函数就可以用我们以前学过的梯度下降法来处理,也就是我们要找到一个好的 h ,最小化\sum_{n=1}^{N}u_n^{(t)}\left( -y_nh(x_n)\right)
那是谁在最小化 E_{in}^{u(t)}(h) 呢?从第8讲中我们知道是AdaBoost 里面的算法 \mathcal{A} 。那具体的过程是,第一步,通过下面的最优化:\min _{h} \hat E_{ADA}=\sum_{n=1}^{N}u_n^{(t)}exp\left( -y_n\eta h(x_n)\right)
- y_n= g_t(x_n)的时候,即正确的, summation 里面会得到:u_n^{(t)}exp(-\eta)
- y_n\neq g_t(x_n)的时候,即错误的, summation 里面会得到:u_n^{(t)}exp(\eta)
由第8讲中:
\epsilon _t=\frac{\sum_{n=1}^{N}u_n^{(t+1)}[\![y_n\neq g_t(x_n) ]\!]}{\sum_{n=1}^{N}u_n^{(t+1)}}
在上一小节当中,我们已经知道 AdaBoost 的整个错误函数优化对应的数学表达式如下:
\min _{\eta}\min _{h} \frac{1}{N}\sum_{n=1}^{N}exp\left(-y_n\left(\sum_{\tau =1}^{t-1}\alpha _\tau g_\tau(x_n) +\eta h(x_n)\right)\right)
然后,我们继续优化,到了这一步,我们要最小化的 h 只是一个方向,我们可以在后面的 \eta 来控制它的步长。所以我们要最小化的是:\min _h\text{constants}+\frac{\eta}{N}\sum_{n=1}^{N}2h(x_n)(s_n-y_n)
我们这次讲神经网络,之前我们学过感知机,那么如果我们把感知机做Linear Aggregation,会发生什么样的变化呢?
例如:
G(x) = \text{sign} \left( \sum_{t=1}^{T} \alpha_t \underbrace{ \text{sign}(w_t^T x)}_{g_t(x)} \right)
Neural Network Hypothesis的输出只是一个线性模型,即把上一层的输入做线性组合再通过决策函数,这个线性模型是任意的。我们在这里只考虑用平方函数当做错误函数的回归。
神经网络里的每一个神经元里都有一个转换函数,那么我们应该使用哪种转换函数呢? 其实不管是线性转换函数或者阶梯状转换函数都是有各自的缺点的:比如线性转换函数让整个模型都是线性函数而缺乏意义,阶梯函数是离散的并且难以优化。较流行的一种选择是使用双曲函数\tanh(x),它更加容易优化,它与我们之前讲过的s型函数有这样的关系:
\tanh(s) = 2 \theta(2s) - 1
\begin{matrix} \text{输出} x_{j}^{(l)}: \left \{ \begin{matrix} \tanh(s_j^{(l)}) & l \lt L\\ s_j^{(l)} & l = L\\ \end{matrix}\right. \end{matrix}
如何决定神经网络好的权重呢?换一句话说,如何决定让神经网络的E_{in}降低的权重呢?如果神经网络只有一层的话,那么这个神经网络基本上就是感知机的aggregation,那么我们可以用以前学过的gradient boosting,也就是一个一个地决定隐藏的神经元。
如果是多层的的情况呢?或许不能这样做。我们考虑一个关系,如果我们定义神经网络最后的输出与y_n的差别:
e_n = \left(y_n - \text{NNet} (x_n) \right)^2
初始化权重,for t = 0,1,...,T
1.stochastic:在n \in \{ 1,2,...,N\}随机选取一个点
2.向前计算出所有的x_i^{(l)}
3.向后计算出所有的\delta_j^{(l)}
4.更新梯度:w_{ij}^{(l)} \leftarrow w_{ij}^{(l)} - \eta x_i^{(l - 1)} \delta_j^{(l)}
return g_{\text{NNET}}(X) = \\ \left( \cdots \tanh \left( \sum_j w_{jk}^{(2)} \cdot \tanh \left( \sum_i w_{ij}^{(1)} x_i \right)\right)\right)
实际使用算法的时候我们可能选取的既不是SGD也不是GD而是针对第一到第三步选取许多点来做,再一起更新,称为mini-banch,这样效果会比较好。
以上就是基本的神经网络算法,其通过反向来计算梯度再更新的方式对权重做最佳化。
神经网络的Error Function:
E_{in}(W) = \\
\frac{1}{N} \sum_{n = 1}^{N} \text{err} \left(\left( \cdots \tanh \left( \sum_j w_{jk}^{(2)} \cdot \tanh \left( \sum_i w_{ij}^{(1)} x_i \right)\right)\right), y_n \right)
之前我们讲到Neural Network,那么对于Neural Network的结构我们该如何来决定呢?而决定Neural Network的结构就是深度学习的一个核心问题。
我们先来对比一下浅层神经网络和深层神经网络:
\begin{matrix}{}
Shallow & Deep \\
效率高&难以训练\\易于排布&难以排布\\理论上powerful&非常powerful\\
\end{matrix}
1.每一层承担简单任务,从后向前逐渐变得复杂
2.擅长求解对拥有原始特征的困难问题
深度学习拥有很多应用之处,也有许多的困难和challenge,例如:
- 难以决定架构
- 模型复杂度很高
- 难以最优化
- 计算复杂度很高
那现在研究者主要用那些方法应对以上这些困难呢?
- 难以决定架构:具体问题具体调整,如卷积神经网络
- 模型复杂度很高:大数据领域这不是问题,而且可以使用regularization
- 难以最优化: 谨慎选取起始点,做pre-training
- 计算复杂度很高: GPU并行计算使得计算更加快捷
我们现在简要介绍如何做深度学习,第一步当然是决定权重的初始值了,那么怎么决定呢?一个比较可能的想法是一层一层来决定,而且是先决定第一层, 继而决定第二层,每次一层,直到完成所有层的初始化(pre-training)。
如何做pre-training呢?也即是:如何决定pre-training的weight呢?我们回头想一想weight的物理意义我们可以发现,实际上,weight就代表了把上一层的输出的信息做一个转换,亦或者说做一个编码,然后传输给下一层。如果我们能够让下一层接收到编码之后的信息所代表的信息是和上一层是基本一样的话,我们认为这就是好的weight,也就是完成了information-preserving encoding的过程,也就是编码之后准确的解码的过程。
那么如何搭建Information-Preserving Neural Network呢?我们可以试着构建一个这样的网络:它的第一层将输入编码到第二层,第二层又将输出解码到第三层,而第三层的输出与第一层的输入类似,我们把这种网络叫做autoencoder:
d- \tilde{d}-d \ \text{NNet with goal} \ g_i(x) \approx X_i
- 对于监督学习来说:可以通过编码的过程得到输入的一些隐藏的结构,从而将它们用于特征转换。
- 对于非监督学习来说:既可以对资料的密度做一个对应;从也可以用来探测离群点。
我们通过Approximating Identity Function,得到了中间的这一层,我们可以得到资料的表现方式,继而作进一步的处理。
那么对于基本的autoencoder,我们如何得到呢?其实autoencoder是一个很简单的浅层的神经网络,而且它的输出等于输入,用BP算法比较容易训练,而且从后层向前我们会做一个压缩的动作,也就是逐渐减少前面层神经元的数目。 通常我们会将W_{ij}^{(1)} = W_{ij}^{(1)}作为regularization。这也就是我们所讲的pre-training的一个基本的思想。
综上,用autoencoder来做DL的基本过程就是:
1.从第一层开始,用autoencoder逐层训练直到最后一层,完成pre-training。
2.BP算法微调完毕所有的\{ W_{ij}^{(l)} \}。
大多数目前的pre-training的方法都是以以上的过程作为基础的。
因为DL结构如此复杂,所以regularization是必须的,我们所讲的:
- 结构化的约束
- 用weight decay or weight elimination来做regularizers
- 在合适的时机停止学习:early stopping
这些方法实际中都是有用的。
这里我们引入引入一种在DL中很有用的regularization方法。将这个之前我们先来复习一下overfitting的原因,我们知道,以下的原因都可能导致overfitting:
- 数据量过少
- noise过大
- 模型太复杂太powerful
其中noise也是一个我们必须着力解决的问题,通常来讲我们会对数据做处理以削弱数据中的噪声,如data cleaning/pruning都是通常会使用的手段。
这里我们讲一个新思路:如果我们在autoencoder的输入里面人为加入噪声,再让autoencoder学习带有noise的data,这样是不是能让autoencoder学习到处理带有noise的数据的能力呢?!答案是肯定的。这就是DL中一个非常强力的做regularization的方法,途径是在数据里面人为的加入noise,这样反而能让NNet在未来的预测之中拥有处理noise的能力,从而表现更好。
由于模型中存在双曲函数\tanh(W^TX), 所以我们之前讲的autoencoder实际上是非线性模型。
那么线性的autoencoder是怎么样的结构呢?其实我们先看看非线性autoencoder的hypothesis:
h_k(X) = \sum_{j = 0}^{\tilde{d}} W_{jk}^{(2)} \tanh
\left(\sum_{i = 0}^d W_{ij}^{(1)} X_i \right)
其中我们做一点变化:
1.为简便丢掉x_o
2.加入约束项W_{ij}^{(1)} = W_{ij}^{(2)} = W_{ij}作为regularization
3.为防止产生意义不大的解,假设输出的维度小于输入的维度\tilde(d) \lt d
这样linear autoencoder的hypothesis:
h_k(X) = \sum_{j = 0}^{\tilde{d}} W_{kj}
\left(\sum_{i = 1}^d W_{ij} X_i \right)
实际上就是矩阵形式:
h(X) = WW^TX
这是一个四次多项式,不易优化,继续推导,对WW^T做特征分解:
WW^T = V \Gamma V^T
\mathop{\max}\limits_{v} \sum_{n = 1}^Nv^Tx_nx_n^Tv \\ s.t. v^Tv = 1
- 从X^TX计算top eigenvectors
- 返回特征转换 \Phi(x) = W(x)
linear autoencoder要最大化的是资料投影到W上的信号强度的平方最大,在统计上有个类似的概念叫做PCA,不过它做的最大化是资料投影到W上的信号强度变化率,算法类似autoencoder:
- x_n \leftarrow x_n - \overline{x} (去均值化)
- 从X^TX计算top eigenvectors
- 返回特征转换 \Phi(x) = W(x - \overline{x})
与autoencoder相比,PCA只是多了一个去均值的动作,这样得到的自然是变化率了。
PCA和linear autoencoder在实际中主要用于线性降维,比如将一个10000维度的资料降维成400维以便学习,也是属于预处理的范畴。
我们介绍RBF(Radial Basis Function) Network,它属于Neural Network的一个分支。之前我们讲过的Gaussian kernel实际上就是RBF kernel:
g_{SVM} (x) = sign \left( \sum_{SV} \alpha_n y_n \exp(- \gamma \Vert x - x_n\Vert^2) + b\right)
\ \ \ \mu:中心点,相当于Gaussian-SVM中的各个SVx_n
\beta_m:投票权重,相当于SVM对偶问题中的\alpha_my_m
从而RBF Network要学习的过程就是给定RBF和要求的输出, 通过学习决定\mu和\beta_m。
以前我们讲过kernel实际上相当于在Z空间计算两个向量的相似性,而RBF就相当于在X空间计算两个向量的距离的相似性。而RBF Network就是用这个对中心距离的相似程度来定义特征转换。
如何求解RBF Network呢?也就是如何求解\mu和\beta_m?首先我们考虑比较简单的想法:如将所有的点都当做中心,而\beta_m在物理意义上就相当于这些中心点对周边的相似的点的影响。我们考虑一个更简单的情况,假设:
\beta_m = 1 \cdot y_m
这样
g_{\text{uniform}} (x) = sign \left( \sum_{m = 1}^{N} y_m \exp(- \gamma \Vert x - x_n\Vert^2) \right)
如好找到好的代表点呢?可以考虑,如果两个样本点非常接近,或许我们不需要两个点同时在RBFNet里起作用,也就是这两个点可以选取同一个代表就可以。进一步讲, 我们把资料分成若干个群,在每一个群里产生一个代表点就可以了。那么怎么解决分群问题呢?这在机器学习里面就是一个典型的非监督而学习的过程,定义E_{in}:
E_{in}(S_1,...,S_M;\mu_1,...,\mu_M) = \frac{1}{N} \sum_{n=1}^{N}\sum_{m=1}^{M}[\![x_n \in S_m]\!]\Vert x_n - \mu_m\Vert^2
1.随机选取k个点当做起始点
2.对E_{in}做最佳化:1.最佳化S_k:把每个点归类到最接近的中心
2.最佳化\mu_k:在每个群里重新决定中心点
...直到收敛
那么我们如何确定这个算法一定会收敛呢?其实是可以保证的:因为算法的每个循环都在让E_{in}最小,而E_{in}的下限就是0,于是算法一定会收敛,一定会停下来。
有了k-Means算法的概念,我们把它用于RBF Network里面就很自然而然了:
1.用k-Means算法得到\{\mu_m\},其中K = M
2.构建特征转换:
\Phi(x) = [\text{RBF}(x_n, x_1),\text{RBF}(x_n, x_2),...,\text{RBF}(x_n, x_M)]
3.把\{(\Phi(x), y_n)\}用线性模型得到\beta
这也是一种非监督学习的方法帮助得到特征转换的应用,如同我们之前讲过的autoencoder。在实际应用中我们通常用validation来调节M(代表点的个数)和\gamma(高斯函数)参数。
从k-Means算法的实际表现来看,通常我们对于k的数量选取合适的话,通常能得到较好的分群结果,而若k的数量选取不合适亦或者初始点选的不好,可能对结果有较大的影响。从实际应用中我们也可以看到如果k-Means得到的中心点比较合理的话,接下来用于RBF Network里面的分类也会做的更加好。
从算法表现上我们也可以看到,Full RBF Network和nearest neighbor算法都做得不错,但是实际应用中它们都因为计算复杂度而很少被使用。
如果机器拿到的资料是抽象的特征,该如何学习呢?比如由Netflix在2006年举办的大赛里面涉及的数据,这些数据包含许多观众对于很多电影的评分,但是除此之外只包含对于观众本身的一些
数据,也就是只有abstract feature,那么又该如何学习呢?
首先我们来进一步看一看抽象的特征,比如一个观众的数据包含的大都是分类的特征,比如ID、血型等。而我们之前见讲过的许多模型都是善于处理数值特征的,如线性模型或者扩展的线性模型如NNet等。目前我们讲过的模型里面只有决策树可以处理分类的特征。
容易想到,如果要让资料易于学习,那么第一步我们可能要做的就是将分类特征转换为数值特征(encoding)。如何转换呢?通常我们用0/1来表示二元向量编码:
A = [1 \ 0\ \ 0\ 0]^T \\
B = [0 \ 1\ \ 0\ 0]^T\\
\cdots
接着上面,式中的Vx我们把它命名为\Phi(x),它代表了特征转换函数,而对于某一部特别的电影,我们可以得到线性模型:
h_m(x) = w_m^T \Phi(x)
1.初始化\{w_m\}\{v_n\}
2.对E_{in}交互的做最佳化:重复
1.最优化w_m:在\{(v_n, r_{nm})\}的第m部电影做线性回归
2.最优化v_n:在\{( w_m, r_{nm})\}的第n位用户做线性回归
...直到收敛
我们要注意初始化值是随机选取的,而和上一讲一样,E_{in}的bound保证了算法最终的收敛。
Linear Autoencoder和Matrix Factorization对比的话,我们可以发现许多相似之处:
对比 | Linear Autoencoder | Matrix Factorization |
---|---|---|
形式 | X \approx W(W^TX) | R \approx V^TW |
构成 | d-\tilde{d}-d | N-\tilde{d}-M |
错误函数 | 所有的x_{ni}的均方误差 | 已知的r_{nm}的均方误差 |
解决方法 | X^TX整体的最佳解 | 交互矩阵的局部最佳解 |
作用 | 特征的降维 | 提取隐藏特征 |
Stochastic Gradient Descent也可以被用于前面问题的求解。SGD也就是每次选取 一笔资料,在这笔资料上用梯度下降做最优化。它的好处是,每一次的最优化很有效率,容易实现,而且容易延伸到其他的错误衡量方式。
那我们如何用SGD求解我们Matrix Factorization呢?首先定义Error Function:
\text{err}(n, m, r_{nm}) = (r_{nm} - w_m^T v_n)^2
也就是用平方错误来衡量预测与真实值之间的误差。
分别用Error Function对v_n和w_m做偏微分:
\nabla_{v_n}\text{err}(n, m, r_{nm}) = - 2(r_{nm} - w_m^T v_n)w_m\\
\nabla_{w_m}\text{err}(n, m, r_{nm}) = - 2(r_{nm} - w_m^T v_n)v_n
随机选取特征向量:初始化\{w_m\}\{v_n\}
for t = 0,1,...,T
1.随机选取某个点(n, m)
2.计算余数\tilde{r}_{nm} = (r_{nm} - w_m^T v_n)
3.更新SGD:
v_n^{new} \leftarrow v_n^{old} + \eta \cdot \tilde{r}_{nm} w_{m}^{old}
w_n^{new} \leftarrow w_n^{old} + \eta \cdot \tilde{r}_{nm}
SGD因为计算方便,是最常用的大型矩阵分解的中的方法。
到这里我们对我们这几讲所提到的这些模型做一个定义:Extraction Models,为什么叫做Extraction Models呢?因为这些模型用特征转换表示了从资料里面学习到的隐藏的可能性,它们是线性模型的延伸。
例如Neural Network/Deep Learning:前面的几层在做特征转换, 最后一层是线性模型,我们所做的是同时做成了隐藏的变数的转换和线性模型。
在RBF Network里呢:
隐藏的变数就是RBF的中心点,后面也是用权重做线性模型。
在Matrix Factorization里:
使用者的特征和电影的特征都承担了这两个角色,因为它们是对称的。
在Adaptive/Gradient Boosting:
它找出的特征转换就是许多的g_t,再做线性模型。
在k Nearest Neighbor里:
每一个看过的点的附近的邻居的范围当做特征转换,再结合权重(每一个点作投票,就是原本点的label)。
这些模型蕴含各自从资料里面萃取(Extraction)出特征的技巧.
在Adaptive/Gradient Boosting:用函数的梯度下降来萃取g_t, 还有autoencoder得到初步的特征转换。
在Neural Network/Deep Learning里:用SGD(BP)计算梯度的值
在RBF Network里呢:我们使用的是k-means clustering,这里我们可以看出非监督式学习对于学习资料的表现方式上是很有效的。
在Matrix Factorization里面:
用基本的SGD或者看成交互的线性回归的话,还可以用alternating leastSQR来解决。
而k Nearest Neighbor:
通常被称为lazy learning,因为在学习上不花功夫,在测试的时候做一些推论的动作。
这些Extraction Models都有哪些优缺点呢?
Pros | Cons |
---|---|
电脑自动完成特征转换:减少了人类的负担 | 这些最佳化问题通常是非凸的:可能伴随各种问题 |
如果隐藏变量足够多,模型非常强力 | 模型复杂带来Overfitting:需要regularization或者validation |
我们来讲Exploiting Numerous Features的技术,首先是Kernel,利用Kernel我们可以把一些数值特征非常多的特征转换\Phi以及内积转化到Kernel里。
段落引用
1. Polynomial Kernel:放缩的多项式转换
2. Gaussian Kernel:无限多维的转换
3. 作业里提到的Stump Kernel:把许多decision-stumps作为转换
4. Sum of Kernels:Kernel相加,代表把不同的转换混合起来
5. Product of Kernels:Kernel相乘,代表把两个Kernel里面埋藏的特征转换组合形成一个新的复杂的转换
6. Mercer Kernels:Kernel需要符合的条件是Mercer's Condition,我们可以说任何符合这个条件的函数里面都埋藏了一些特征转换
继而Kernel可以搭配各种模型,如SVM、SVR、 probabilistic SVM、kernel ridge regression、kernel logistic regression等,使得原来的模型能做非常广泛的延伸。而我们之后讲的PCA,k-Means等里面有线性或者内积运算的模型都可以加上Kernel形成新的版本。
我们运用特征转换的第二种方法是Aggregation:也就是用许多的\Phi也就是许多的g_t来预测特征。其中Decision Stump可以看成是最简单的perceptron,也可以看成是最简单的simplest DecTree。而复杂的Decision Tree可以看成是把资料切分再组合。(Gaussian) RBF通过许多个代表g_t也就是每个中心点以及中心点的影响力来预测某些点。
上面讲的这三者都是我们可以用来组合的单独的g_t,运用这些许多g_t,我们可以用它们来投票再平均, 或者把它们做线性组合、有条件的组合亦或者是非线性组合。
除了上面的方法我们还可以用其他的方法得到g_t:
如Bagging来得到许多g_t,再组合起来,如果再配合Decision Tree就会形成Random Forest。如果是一步一步找出g_t,我们可以用AdaBoost或者GradientBoost。而DecisionTree本身就是找出不一样的g_t的方法,之前讲过的Nearest Neighbor中的投票也是一种把g_t的预测合起来的方法。而probabilisticSVM中的微调也是类似Aggregation的方法。机器学习许多不同的模型都是有互相关联的地方的。
我们要讲的第三个面向特征方向就是把一些潜藏的特征找出来,而这个潜藏的特征也是要做最佳化的变数,我们可以把这些潜藏的特征和权重,一起做最佳化,这里面常用到非监督式学习的方法。
例如Neural Network;Deep Learning neuron weights代表了我们要做的特征转换;或者RBF Network中的RBF centers也代表了特征转换;或者Matrix Factorization中的user/movie factors也是特征转换。
使用的非监督学习方法有:
在RBF里是k-Means方法,来找到群的中心;在矩阵分解里面,我们常用Autoencoder或者PCA,它们所萃取出的是投影过去的最好的方向;而我们在AdaBoost和GradientBoost所要找出的一步一步g_t,也是在萃取参数。
这些方法也是可能有机会融合起来使用的,比如在Neural Network里面使用GradientBoost找出神经元,亦或者在萃取出来的特征用于神经网络做最佳化。
第四个和特征转换相关的方面就是降维,也就是原有维度的压缩。例如Decision Stump或者DecTree Branching,我们可以把它的分支看出都是在对低维度做投影;而在Random Forest或者Tree Branching里面通常是先做投影,再在上面切stump;在Autoencoder或者PCA里面也是想对低维度做投影,并且保持资料含有的信息;在Matrix Factorization中,我们做的也是想把一个非常高维度的向量投影到一个低维度的具体的向量上面。
而之前在随机森林里面讲的特征选择Feature Selection也是一种降维的方式,而很多其他的降维方式也可能被运用。
现在我们讲数值优化方法,我们第一常用的就是梯度下降法,每次梯度下降都是相当于错误函数的一次逼近:
\text{new} = \text{old} - \eta \nabla E
- 如(Kernel) LogReg
- Neural Network(配合[backprop])
- Matrix Factorization以及Linear SVM(本节课没有讲,实际上SGD常用)。
而在AdaBoost或者GradientBoost我们用的是Functional GD,也就是我们下降的是函数而不是方向,而且Steepest Descent,也就是每一步下降的很多。梯度下降法也会配合二次逼近或者加上约束来操作。
当我们遇到一些困难的原始问题,我们通常经过数学推导或者加上我们对这个问题了解的知识来让这个问题做一些变形,如:
- Dual SVM,通过凸二次规划来转化Kernel LogReg或Kernel RidgeReg,通过representer理论来转化
- PCA:转化为eigenproblem来解决
其中线性代数,或者最佳化理论都有涉及。
其他的一些boosting模型或者Kernel模型的解法里面都有用到这种转化的思想和技术。
还有那些最佳化的方法呢? 比如我们遇到了难以解决的问题,有时候我们需要把这些困难的问题拆分成多层问题来求解。如:
Multi-Stage
probabilistic SVM;
linear blending;
stacking;
RBF Network;
DeepNet pre-training
或者我们对于有两组变数交织在一起的时候我们可以交互的做最佳化,如:
k-Means;
alternating LeastSqr;
(steepest descent)
或者我们可以把问题分而治之,如:
decision tree;
这些手段实际中都是常用到的。
在机器学习里面我们也常常需要通过Regularization来对付Overfitting Elimination,手段也有许多,如:
- large-margin:SVM和AdaBoost (indirectly)
- L2:SVR;kernel models;NNet [weight-decay]
- voting/averaging(投票取平均)uniform
- blending;Bagging;Random Forest
- denoising:在autoencoder人工加入杂讯以对抗杂
- pruning:在decision tree里面cutting trees,让模型复杂度减小
- weight-elimination:在NNet里想办法让weight变小一点
- early stopping:NNet (any GD-like)
- constraining:
autoencoder里的对权重的约束;
RBF里面对于中心的约束;
以上这些都是Regularization的方法,就是在设计模型的时候就减少参数的使用或者加上一些条件或限制,也就是相当于开车时踩刹车的动作。
我们也可以通过Validation来对抗Overfitting,如
Random Forest里面的OOB(out of bag)方法,或者SVM/SVR里的SV就可以用来检查复杂度,有一些内部的操作里面也包含了Validation的动作:如blending或DecTree pruning。
KDDCup 2010使用的是线性融合模型,其中一个部分对原始资料做编码以后再做逻辑回归,另外一个部分随机森林里使用的是人为设计的特征。
KDDCup 2011使用了有NNet、决策树以及线性融合模型,其中包括了:
矩阵分解、限制波兹曼机、k近邻以及Probabilistic Latent Semantic Analysis。
KDDCup 2012使用了NNet, GBDT-like, 然后是线性融合模型,包括线性回归、逻辑回归等。
成功的秘诀是系统的做好blending的动作。
KDDCup 2013使用了Random Forest, GBDT以及人为设计特征,而人类学习和机器学习做配合也是成功的一大秘诀。
ICDM 2006 Top 10 Data Mining Algorithms:
- C4.5: 是决策树的一种
- k-Means:学过
- SVM:学过
- Apriori: 数据挖掘方法,找出数据里面经常出现的部分
- EM: 最佳化技巧里面的‘alternating
optimization’ 用于几率模型的一个特例- PageRank: 谷歌的网页排名技术类似
matrix factorization矩阵分解- AdaBoost 学过
- k Nearest Neighbor 学过
- Naive Bayes: 通过资料的统计特性来决定的线性模型
- C&RT:学过,决策树
还有没有列上去但是足够重要也应该被列上去的的方法如:
- 线性回归
- 逻辑回归
- 随机森林
- Gradient Boosting Decision Tree
- NNet。
通过学习本课程我们希望从课程延伸到更广泛的地方,希望大家机器学习的丛林不会迷路。