上学期花了一个多月读完了李航老师的《统计学习方法》,现在带着新入团队的新同学以读书会的形式读这本书,书里边全是干货,对于我理解基本的机器学习算法很有帮助,也笔头做了一些总结(不完全基于此书),现将其摘录于此作为在博客园的第一篇博客。因为并不是为了扫盲,所以仅仅是抓出脉络以及关键点,方便以后快速温习,而不是预习。
概论
机器学习很多时候也被称作统计机器学习,这是因为大部分机器学习方法或多或少基于统计的方法,或者有基于统计方法的版本,即便是早期不涉及统计方法的算法在后来也都有了统计学的解释。
统计学习的三要素:模型、策略、算法,决定了一个统计学习的方法。整本书的算法均可从这三个思路去思考,并且从这三个思路思考可以培养一定的统计建模的意识。
- 模型是一个可以根据合法输入产生输出的“黑盒子”,也即一个从输入空间(或特征空间)到输出空间的映射。
- 策略是衡量模型好坏的一个判断标准,以此可以确定向什么方向修改/优化模型。
- 算法是确定了模型和策略,为了尽量满足策略所采用的优化模型的做法。
简单的说,整个学习就是要学习出一个模型,而策略决定了我们所想要的模型,而算法是用来得到模型参数所采用的方法而已。
这本书讨论的是有监督学习,而对于有监督学习来说,共有的一个问题就是过拟合问题(overfitting),简单地来讲,这是模型过分“迎合”训练数据而导致模型在训练数据上表现良好,而对未知输入的泛化能力很差的现象。
首先,过拟合是无法避免的。毕竟统计学习在训练时避免不了要拟合训练数据,这是因为我们的模型参数就是由训练数据训练而来的。这里的“过”指的是模型过于复杂(迎合数据),导致泛化能力急剧下降。这里举个例子:
这里有多少盒子在树后?按照我们的直觉应该是只有一个盒子,然而事实上可能是:
显然,根据我们的直观认识,对于一个未知的参数(即这里的盒子数),越简单可能越符合我们的先验知识。也即简单的模型对未知的情况泛化能力更高(更加可能是对的)。所以“从贝叶斯估计的角度来看,正则化项对应于模型的先验概率”,模型越复杂,先验越小(经验告诉我们如此复杂的情况不太可能)。
因此,一个自然的想法便是要在策略中限制这种复杂的模型,虽然其在训练数据上比简单模型的表现更好。最常见的思路的就是添加正则化项,此项表示了模型的复杂度。在策略中和原始目标求和,即可得到既能得到较大的目标函数值,又不使模型较为复杂的模型参数。一个最简单的例子就是线性回归。
另一个常用的方法即交叉验证,意思是将训练数据分块,一部分作为训练数据,一部分作为测试数据,多次不同地分块以后取在测试数据上表现最优的模型参数。这种方法的缺点是计算开销太大,毕竟要多训练很多次模型。
感知机
这是一个线性的模型,意在用一条线(超平面)对训练数据进行二分。
- 输入:训练数据的特征向量
- 输出:二值类标
前提是数据严格线性可分,即存在一条线(超平面)能将正负例完美分开。而学习的目的即为学出这个分离线(超平面)。
学习的策略为经验风险最小化,即误分类点数最少,而假设是线性可分,因此误分类点数一定可以降为0。但是,误分类点数并不能指导我们如何修改模型(不能导出有效的算法),因此我们修改了一下策略的表示,改为误分类点到分离平面的距离之和。因此损失函数为:
\begin{equation}
L(w, b) = -\sum\limits_{x_i\in M} y_i(w_i+b)
\end{equation}
其中,(M)为误分类点集,(w)和(b)为参数,(y_i)是标准类标,乘上(y_i)乘积保证为正。为求其极小,分别对参数求导并令其导数为0即可:
\begin{align}\notag &\nabla_w L(w, b) = -\sum\limits_{x_i\in M}y_ix_i \\\\ &\nabla_b L(w, b) = -\sum\limits_{x_i\in M}y_i \end{align}
学习算法为梯度下降法,有原始形式和对偶形式之分。 **原始形式核心递归式:**\begin{align}\notag &w_{new} = w_{old}+\eta y_{i}x_{i} \\\\ &b_{new} = b_{old}+\eta y_{i} \end{align}
其中\(\eta\)为梯度下降的步长。初始值\(w\)和\(b\)随机初始化。 如果将\(w\)和\(b\)初始化为0,那么根据原始形式的递归式,\(w\)和\(b\)分别可以写作\(y_{i}x_{i}\)和\(y_{i}\)的线性组合形式,即:\begin{align}\notag &w = -\sum\limits_{i=1}^{N}\alpha_{i}y_{i}x_{i} \\\\ &b = -\sum\limits_{i=1}^{N}\alpha_{i}y{i} \end{align}
系数相同的原因是因为每次更新w和b走过了相同个数的步长。这样就能将对\(w\)和\(b\)的更新改为对\(\alpha\)和\(b\)的更新,节约了乘法的计算开销。 **对偶形式的核心递归式:**\begin{align}\notag &\alpha_{i} = \alpha_{i}+\eta \\\\ &b = b+\eta y_{i} \end{align}
注意到感知机算法的梯度下降法是用的随机梯度下降,即每次随机选择一个误分点进行更新,而没有使用批量梯度下降,这是因为感知机是必然线性可分的,也即最后超平面必然存在,即算法必然收敛,因此可以选择计算开销更小的随机梯度下降法。 #KNN算法 根据近邻来估计实例点的属性。有两种方式,一种是Top-K最近邻,一种是根据距离确定近邻。前者算最近的k个邻居,而后者计算离实例的距离在一定范围以内的所有邻居。分别适用于分布密集和分布稀疏的情况。 KNN算法最大的问题在于计算pair之间的距离,这是\(O(n^2)\)的问题,而每次增加点,都需要进行N次计算,这是不可接受的,于是对实例存在的特征空间进行切分,具体算法即kd树算法。按维度进行切分,思想类似于二分查找。 #朴素贝叶斯 模型为条件概率模型,即目的为学习一个条件概率分布(和一个先验分布)。 - 输入:实例的特征向量 - 输出:多值类标模型假设:对于任一实例,在已知类标时,各特征相互独立。这其实是将指数级参数个数((2^n))的联合分布降为了线性参数个数((2n+1))的条件概率与先验之积。
\begin{equation}
P(c_k|x_1, x_2, \dots, x_n) = \frac{P(x_1, \dots, x_n|c_k)\cdot P(c_k)}{P(x_1,x_2, \dots, x_n)}
\end{equation}
由于分母是平凡的,对于相同实例不同类标都是相同的。因此可以略去。分母中的条件概率因为模型假设,可以写为:
\begin{equation}
P(x_1, \dots, x_n | c_k) = \prod\limits_{i=1}^{n}P(x_i|c_k)
\end{equation}
策略是期望风险最小化,即分类正误的期望,可等价于后验概率最小化(证明略)。也即只用找到后验概率最大的类标赋给实例即可。这里模型未知参数为(P(x_i|c_k))和(P(c_k)),为了估计其值,使用的是极大似然估计,通俗的说就是用训练样本中对应项出现的频率来作为估计的概率(因为极大似然估计和强假设,因此被叫做朴素贝叶斯,或者傻瓜贝叶斯)。
所有涉及到共现矩阵,也即观测的频率,以及概率的算法,都需要考虑概率值为0的情况,或者分母为0的情况。朴素贝叶斯加入拉普拉斯平滑使避免出现0。
决策树
if-then结构的树,目的即为学习出这样一棵树,非叶子节点是特征,叶子节点是类标。
- 输入:特征向量
- 输出:多值类标
策略是特征选择,越靠近根的特征应该有更好的区分能力,然而这一条件无法直接指导算法优化,因此引入信息增益定义。
几个定义:
- 熵:表示随机变量X的不确定程度:
\begin{equation}
H(X) = -\sum\limits_{i=1}^{n}P_i\log P_{i}
\end{equation}
这里遍历了X可能的i个取值,限制条件为所有取值概率之和为1 - 经验熵:将数据集D做分类的不确定程度:
\begin{equation}
H(D) = -\sum\limits_{k=1}^{K}\frac{\vert C_k\vert}{\vert D\vert}\log\frac{\vert C_k\vert}{\vert D\vert}
\end{equation}
其中D可被分成K个类,并且第k个类的实例个数为(\vert C_k\vert),D中实例个数为(\vert D\vert) - 经验条件熵:给定特征下,将数据集做分类的不确定性(用分成某子类的概率对子类的经验熵进行加权)。
\begin{equation}
\begin{aligned}
H(D|A)&=\sum\limits_{i=1}^n\frac{|D_i|}{D}H(D_i) \\
&=-\sum\limits_{i=1}^n\frac{|D_i|}{|D|}\sum\limits_{k=1}^K\frac{|D_{ik}|}{|D_i|}\log\frac{|D_{ik}|}{|D_i|}
\end{aligned}
\end{equation}
然后信息增益可以定义为:给定特征A时D上的经验熵与经验条件熵之差。
\begin{equation}
g(D, A) = H(D)-H(D|A)
\end{equation}
定义信息增益比:信息增益与数据集关于特征A的值的熵之比。
\begin{equation}
g_{R}(D, A) = \frac{g(D, A)}{H_A(D)},
\end{equation}
其中(H_{A}(D) = -\sum\limits_{i=1}^n\frac{|D_i|}{|D|}\log\frac{|D_i|}{|D|}),n是A可取的值的个数,(D_i)是根据特征A进行分类以后得到的子类,可以被看作是经验熵。
算法中,ID3算法递归建树,对每个节点,选择当前使信息增益最大的特征。C4.5算法,用信息增益比来替代ID3中的信息增益。这是因为消息增益越大,表明该特征对全局熵减少得也就最大,也即能使全局不确定性降低最大,若一个特征可以取的值越多,每个分支下的实例数就越少,相应的不确定程度就越低,换句话说,信息增益会偏向取值更多的特征,因此ID3算法偏向生成那种宽而浅的树,这其实是不合理的。而信息增益比用经验熵做约束,惩罚了取值数多的特征,因此可以得到更好的树。
决策树模型为了防止过拟合,需要一定的剪枝,其做法是用节点个数作为正则化项。
CART算法(建树、剪枝),用即你最小化建二叉树,即对于所有可能的特征的所有可能取值,取基尼最大的作为当前节点特征。
基尼指数:
\begin{equation}
\text{Gini}(p) = \sum\limits_{k=1}^K p_{k}(1-p_{k})=1-\sum\limits_{k=1}^Kp_k^2
\end{equation}