第一章 绪论
机器学习
Arthur Samuel 的定义:在不被明确定义的情况下,给予计算机学习的能力的研究领域。
Tom Mitchell 的定义:计算机从经验 E E E 中学习,解决某一任务 T T T ,进行性能度量 P P P 。通过 P P P 评测其在任务 T T T 上的表现,这个表现会因为 E E E 而提高。
常见的机器学习算法:监督学习、无监督学习。
监督学习
监督学习给予机器学习算法一个包含“正确答案”的数据集,即训练集中含有标签(label)。
监督学习可以被分为两类问题:
回归问题 :预测连续值,如预测房价。
分类问题 :预测离散值,如预测肿瘤是否良性。
无监督学习
无监督学习仅仅给予机器学习算法一个数据集,不包含标签,要求算法从数据中发掘数据的结构。这种问题被称作为聚类问题。
无监督学习的常见应用:
新闻聚类 :将讨论同一件事新闻放到一起。
基因工程 :判断某一基因在不同的人身上表达的程度。
计算集群组织 :通过聚类算法判断哪些机器趋向于协同工作,将这些机器放在一起有助于节省资源。
社交网络分析 :识别同一个圈子中的朋友,并且判断哪些人互相认识。
市场细分 :将公司客户划分到不同的细分市场,以进行更加精准的推荐。
天文分析 :帮助探索星系的形成。
音频分离 :鸡尾酒聚会问题。
第二章 单元线性回归
模型表示
在训练集中,定义一些符号:
m m m :训练集的大小。
x x x :输入变量 / 特征。
y y y :输出变量 / 标签。
基于上述符号,可以使用 ( x , y ) (x, y) ( x , y ) 来表示一个训练样本。具体地,使用上标 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) ( x ( i ) , y ( i ) ) 来表示第 i i i 个训练样本。
学习算法的目的是根据给定的数据集,找到一个假设函数 h h h ,其输入为 x x x ,输出为 y y y 。在单元线性回归中,假设 y y y 与 x x x 呈线性关系,即 h θ ( x ) = θ 0 + θ 1 x h_{\theta}(x) = \theta_0 + \theta_1 x h θ ( x ) = θ 0 + θ 1 x ,其中 h θ ( x ) h_{\theta}(x) h θ ( x ) 表示 h h h 是关于 x x x 的函数,可训练参数为 θ \theta θ ,有的时候,h θ ( x ) h_{\theta}(x) h θ ( x ) 也会被简写成 h ( x ) h(x) h ( x ) 。
损失函数
给定训练集,要求找到一个合理的 h h h ,因此如何确定 θ \theta θ 的值就成为了一个重要的问题。一个直观的想法是:选择对于每个训练样本 ( x , y ) (x, y) ( x , y ) 都能让 h ( x ) h(x) h ( x ) 与 y y y 接近的 θ \theta θ 。因此通过需要一个函数 J ( θ ) J(\theta) J ( θ ) 来度量 h ( x ) h(x) h ( x ) 与 y y y 的接近程度。
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \dfrac{1}{2m}\sum\limits_{i=1}^m \left(h_{\theta}(x^{(i)}) - y^{(i)}\right)^2
J ( θ ) = 2 m 1 i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) 2
其中平方是为了将负数的距离变成正数,1 m \dfrac{1}{m} m 1 是对所有训练样本取平均,1 2 \dfrac{1}{2} 2 1 是为了方便求导。这个函数被称作为损失函数 。而训练的目标就是最小化损失函数,即:
m i n i m i z e θ J ( θ ) \underset{\theta} { {\rm minimize } }\ J(\theta)
θ m i n i m i z e J ( θ )
梯度下降
现在我们拥有一个函数 J ( θ 0 , θ 1 ) J(\theta_0, \theta_1) J ( θ 0 , θ 1 ) ,我们要求其最小值以及对应的 θ \theta θ 值。在没有求最值公式的情况下,一个暴力的方法是:先随机指定 θ 0 \theta_0 θ 0 和 θ 1 \theta_1 θ 1 的值,接着不断调整它们的值,使得 J ( θ 0 , θ 1 ) J(\theta_0, \theta_1) J ( θ 0 , θ 1 ) 变小,最后 J ( θ ) J(\theta) J ( θ ) 会收敛到一个局部最小值。
如何使 J ( θ ) J(\theta) J ( θ ) 下降的速度最快,那就是往梯度的反方向更新参数了。具体地,重复以下步骤直至收敛:
θ i : = θ i − α ∂ ∂ θ i J ( θ ) , ( i = 0 , 1 , … ) \theta_i := \theta_i - \alpha \dfrac{\partial}{\partial \theta_i}J(\theta), (i = 0, 1, \dots)
θ i : = θ i − α ∂ θ i ∂ J ( θ ) , ( i = 0 , 1 , … )
其中 α \alpha α 是学习率,用于控制参数更新的幅度和下降的速率。对于梯度下降算法,有两点值得注意:
不同参数需要同步更新,以保证所有参数是根据同一个梯度进行更新。
不同的初始值可能导致最后收敛到不同的局部最优值。
学习率对梯度下降的影响:
如果学习率过小,会导致梯度下降收敛得很慢。
如果学习率过大,会导致损失函数难以收敛,甚至发散。
这里所说的梯度下降算法也被称作为 Batch 梯度下降,Batch 是指每一步梯度下降都遍历了整个训练集。
第三章 线性代数
矩阵和向量
矩阵是由数字组成的二维数组,其维度被定义为行数 × \times × 列数。对于矩阵 A A A ,用 A i , j A_{i, j} A i , j 表示矩阵 A A A 中第 i i i 行第 j j j 列的元素。
向量是一个 n × 1 n\times 1 n × 1 的矩阵,其维度就是 n n n 维。对于向量 y y y ,用 y i y_i y i 表示向量 y y y 中的第 i i i 个元素。
矩阵的加法与数乘
只有两个同型矩阵(维度相同)才能相加。两个 n × m n\times m n × m 的矩阵相加,得到的结果是每个元素对应相加。即若 C = A + B C = A + B C = A + B ,那么 C i , j = A i , j + B i , j C_{i, j} = A_{i, j} + B_{i, j} C i , j = A i , j + B i , j 。
矩阵的数乘,其结果是矩阵中的每一个元素与标量相乘。即若 B = α A B=\alpha A B = α A ,那么 B i , j = α A i , j B_{i, j} = \alpha A_{i, j} B i , j = α A i , j 。
矩阵的加法和数乘均不改变矩阵的形状。
矩阵向量乘法
一个矩阵左乘一个向量,向量的维数必须与矩阵的列数相等。即一个 n × m n\times m n × m 的矩阵只能与一个 m m m 维的向量相乘。结果为一个 n n n 维向量,其第 i i i 个元素矩阵的第 i i i 行与向量逐元素相乘再相加的结果,即如果矩阵 A A A 与向量 y y y 相乘得到了向量 z z z ,那么:
z i = ∑ j = 1 m A i , j y j z_i = \sum\limits_{j = 1}^{m} A_{i, j}y_j
z i = j = 1 ∑ m A i , j y j
可以将矩阵向量乘法的思想运用到线性函数的计算中,假设 x 1 , x 2 , x 3 , x 4 x_1, x_2, x_3, x_4 x 1 , x 2 , x 3 , x 4 是四个输入,线性函数是 h ( x ) = θ 0 + θ 1 x h(x) = \theta_0 + \theta_1 x h ( x ) = θ 0 + θ 1 x ,那么有:
[ 1 x 1 1 x 2 1 x 3 1 x 4 ] × [ θ 0 θ 1 ] = [ h ( x 1 ) h ( x 2 ) h ( x 3 ) h ( x 4 ) ] \begin{bmatrix}
1 & x_1 \\
1 & x_2 \\
1 & x_3 \\
1 & x_4
\end{bmatrix}
\times
\begin{bmatrix}
\theta_0 \\
\theta_1 \\
\end{bmatrix}
=
\begin{bmatrix}
h(x_1) \\
h(x_2) \\
h(x_3) \\
h(x_4)
\end{bmatrix}
⎣ ⎢ ⎢ ⎢ ⎡ 1 1 1 1 x 1 x 2 x 3 x 4 ⎦ ⎥ ⎥ ⎥ ⎤ × [ θ 0 θ 1 ] = ⎣ ⎢ ⎢ ⎢ ⎡ h ( x 1 ) h ( x 2 ) h ( x 3 ) h ( x 4 ) ⎦ ⎥ ⎥ ⎥ ⎤
通过这样的方式,我们可以将多次线性运算转换为一次矩阵运算。具体可以表示为:
P r e d i c t i o n = D a t a M a t r i x × P a r a m e t e r s \rm Prediction = DataMatrix \times Parameters
P r e d i c t i o n = D a t a M a t r i x × P a r a m e t e r s
矩阵乘法
两个矩阵相乘,后一个矩阵的行数必须与前一个矩阵的列数相同,得到的矩阵的维度维:前一个矩阵的行数 × \times × 后一个矩阵的列数。这意味着,一个 n × m n\times m n × m 的矩阵与一个 m × o m\times o m × o 的矩阵相乘,结果为一个 n × o n\times o n × o 的矩阵。
矩阵乘法的计算,可以看成多个矩阵与向量乘法计算的拼接。具体地,将 m × o m\times o m × o 的矩阵的第 i i i 列提取出来,与 n × m n\times m n × m 的矩阵进行乘法运算,就得到了结果矩阵的第 i i i 列。将全部 o o o 列计算完毕之后,拼接起来就得到了最终的计算结果。
同矩阵向量乘法相同。矩阵之间的乘法可以对数据矩阵同时进行多种线性运算,假设有两个输入 x 1 , x 2 x_1, x_2 x 1 , x 2 ,两个线性运算 h 1 ( x ) , h 2 ( x ) h_1(x), h_2(x) h 1 ( x ) , h 2 ( x ) ,那么有:
[ 1 x 1 1 x 2 ] × [ h 1 h 2 ] = [ h 1 ( x 1 ) h 2 ( x 1 ) h 1 ( x 2 ) h 2 ( x 2 ) ] \begin{bmatrix}
1 & x_1 \\
1 & x_2 \\
\end{bmatrix}
\times
\begin{bmatrix}
h_1 & h_2
\end{bmatrix}
=
\begin{bmatrix}
h_1(x_1) & h_2(x_1) \\
h_1(x_2) & h_2(x_2)\\
\end{bmatrix}
[ 1 1 x 1 x 2 ] × [ h 1 h 2 ] = [ h 1 ( x 1 ) h 1 ( x 2 ) h 2 ( x 1 ) h 2 ( x 2 ) ]
在进行矩阵乘法时,需要注意:矩阵乘法不满足交换律,但是满足结合律 !
矩阵的逆和转置
单位阵的概念 :n n n 阶单位阵 I I I 是一个 n × n n \times n n × n 的,对角线上全为 1 1 1 ,其余部分为 0 0 0 的矩阵,其满足:A ⋅ I = I ⋅ A = A A \cdot I = I \cdot A = A A ⋅ I = I ⋅ A = A 。虽然矩阵乘法不满足交换律,但是矩阵和单位阵的乘法是满足交换律的。
矩阵的逆 :矩阵的逆是一个类似于倒数的概念。只有方阵 (行数与列数相等的矩阵)才有逆矩阵,矩阵 A A A 的逆矩阵被记作 A − 1 A^{-1} A − 1 。如果矩阵 A A A 是方阵且有逆矩阵,那么 A A − 1 = A − 1 A = I AA^{-1} = A^{-1}A = I A A − 1 = A − 1 A = I 。
矩阵的转置 :将矩阵的行与列交换,成为矩阵的转置。矩阵 A A A 的转置被记作为 A T A^T A T 。具体地:
A i j T = A j i A^T_{ij} = A_{ji}
A i j T = A j i
第四章 多元线性回归
多特征
假设有 m m m 个样本,每个样本具有 n n n 个特征,那么第 i i i 个样本会被表示为:A ( i ) A^{(i)} A ( i ) ,第 i i i 个样本的第 j j j 个特征会被表示为:A j ( i ) A^{(i)}_j A j ( i ) 。
目标函数被表示为:h θ ( x ) = θ 0 + ∑ i = 1 n θ i x i h_{\theta}(x) = {\theta}_0 + \sum\limits_{i=1}^n{\theta_i x_i} h θ ( x ) = θ 0 + i = 1 ∑ n θ i x i 。
令 x 0 = 1 x_0 = 1 x 0 = 1 ,那么目标函数变为:h θ ( x ) = ∑ i = 0 n θ i x i h_{\theta}(x)=\sum\limits_{i=0}^n{\theta_i x_i} h θ ( x ) = i = 0 ∑ n θ i x i 。
将参数和特征写成矩阵(列向量)形式,有:h θ ( x ) = θ T x h_{\theta}(x)=\theta^Tx h θ ( x ) = θ T x 。值得注意的是,此时参数和特征都是 n + 1 n+1 n + 1 维的。
多元梯度下降法
目标函数:h θ ( x ) = θ T x = ∑ i = 0 n θ i x i h_{\theta}(x) = \theta^T x = \sum\limits_{i=0}^n{\theta_i x_i} h θ ( x ) = θ T x = i = 0 ∑ n θ i x i ,其中 x 0 = 1 x_0 = 1 x 0 = 1 。
参数:θ \theta θ (n + 1 n+1 n + 1 维向量)
损失函数:J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \dfrac{1}{2m} \sum\limits_{i=1}^m(h_{\theta}(x^{(i)})-y^{(i)})^2 J ( θ ) = 2 m 1 i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) 2 。
梯度下降更新公式:θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j:=\theta_j-\alpha\dfrac{1}{m}\sum\limits_{i=1}^m(h_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j θ j : = θ j − α m 1 i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) 。
特征缩放(归一化)
归一化的目的:让所有的特征都处于相似大小的范围,以让梯度下降得更快。
假设数据都是正数,μ \mu μ 为数据的平均值,s s s 为数据的标准差。
最大值归一化:x = x x max x=\dfrac{x}{x_{\max} } x = x m a x x 。
均值归一化:x = x − μ x max − x min x=\dfrac{x - \mu}{x_{\max} - x_{\min} } x = x m a x − x m i n x − μ 。
均值方差归一化:x = x − μ s x=\dfrac{x - \mu}{s} x = s x − μ 。
学习率
画出 J ( θ ) J(\theta) J ( θ ) 随训练轮次变化的曲线可以帮助判断梯度下降是否正常运行。如果 J ( θ ) J(\theta) J ( θ ) 在某一段递增,通常是因为学习率设置得过大而引起,这个时候可以将学习率调小。
学习率对梯度下降的影响:
如果学习率过小,会导致梯度下降收敛得很慢。
如果学习率过大,会导致损失函数难以收敛,甚至发散。
在实践中,通常需要尝试多种学习率,找到最适合对应任务的学习率。
特征与多项式回归
有的时候可以将特征进行运算,以让线性回归模型拟合更加复杂的函数。
例如房屋的特征有长度和宽度,我们就可以将长度和宽度相乘,得到房屋的面积,作为一个新的特征输入模型,获得更好的效果。
在多项式回归模型中,每一项可以看成是原始特征进行幂运算之后得到的新特征,当然也可以进行开方、取对数等运算。
具体需要使用哪些特征,要如何组合特征,可以由自己自由选择,也可以使用算法去寻找,这也催生了特征工程这一学科。
正规方程
正规方程方法是一种计算参数 θ \theta θ 最优值的解析方法,它可以一次性计算出参数 θ \theta θ 的最优值,而不需要像梯度下降一样进行多次迭代。
假设特征矩阵 X ∈ R m × n + 1 X\in {\mathbb R}^{m\times n + 1} X ∈ R m × n + 1 ,m m m 表示有 m m m 个样本,n n n 表示有 n n n 个特征,加一是加了一项 x 0 = 1 x_0 = 1 x 0 = 1 。标签矩阵 y ∈ R m y\in {\mathbb R}^{m} y ∈ R m 。那么最优参数 θ \theta θ 可以通过如下公式进行计算:
θ = ( X T X ) − 1 X T y \theta = (X^TX)^{-1}X^Ty
θ = ( X T X ) − 1 X T y
其中 X T X^T X T 表示矩阵 X X X 的转置,( X T X ) − 1 (X^TX)^{-1} ( X T X ) − 1 表示矩阵 X T X X^TX X T X 的逆。数学上可以证明该公式的正确性,在此不进行赘述。
梯度下降法与正规方程法的对比:
梯度下降法需要选择学习率,而正规方程法不需要。
梯度下降法需要通过多次迭代次啊能求解最优值,而正规方程法不需要迭代。
但是梯度下降法在特征数量很多(n n n 很大)的时候依然有着优秀的表现,而正规方程法由于需要求解一个 n × n n\times n n × n 的矩阵的逆,其时间复杂度为 Θ ( n 3 ) \Theta(n^3) Θ ( n 3 ) ,当 n n n 很大时,效率会非常低下。
梯度下降法比正规方程法更加泛用,正规方程法几乎只适用于线性回归。
在使用正规方程法时,如果 X T X X^TX X T X 不可逆,应该怎么办?
在遇到矩阵不可逆但是要求逆的情况时,可以通过求伪逆实现。
另外,矩阵不可逆通常是因为以下两种情况:
不同的特征之间线性相关(特征多余)
特征数量太多(例如特征数量大于样本数量)
要解决这些问题,一般采用删除某些特征,或者正则化的方式。
第五章 Octave 教程
人生苦短,我用 Python 。🐶
第六章 逻辑回归
分类
分类问题是指一类问题,它的输出 y y y 只有两个离散的取值 0 0 0 或 1 1 1 ,如判断邮件是否为垃圾邮件,网上交易是否属于诈骗,肿瘤是否属于恶性肿瘤等。其中,y = 1 y=1 y = 1 的样本被称作为正例;y = 0 y=0 y = 0 的样本被称作为负例。一般来说,我们会将希望找到的东西化为正例,但实际上正例与负例的划分是任意的。
线性回归算法不适用于分类问题,理由有如下两个:
线性回归算法对噪声过于敏感。
线性回归算法的输出值可能大于 1 1 1 或者小于 0 0 0 ,这在所有标签都是 0 0 0 或 1 1 1 的问题中略显奇怪。
因此,本章将引入逻辑回归算法,该算法的输出值会在 0 ∼ 1 0\sim 1 0 ∼ 1 之间。注意:虽然逻辑回归算法中有“回归”二字,但它实际上是一个分类算法。
模型表示
定义 h θ ( x ) h_\theta(x) h θ ( x ) 表示在参数 θ \theta θ 的影响下,给定特征 x x x ,其属于正例 y = 1 y = 1 y = 1 的概率。即:
h θ ( x ) = P ( y = 1 ∣ x ; θ ) h_\theta(x) = P(y = 1\ |\ x;\theta)
h θ ( x ) = P ( y = 1 ∣ x ; θ )
h θ ( x ) h_\theta(x) h θ ( x ) 通过如下公式进行计算:
这里的 g ( z ) g(z) g ( z ) 被称作为 Sigmoid 函数或者 Logistic 函数(逻辑函数)。其具有如下特点:
值域在 0 0 0 到 1 1 1 之间:逻辑函数的输出值范围在 0 0 0 和 1 1 1 之间,当 x x x 趋近于正无穷大时,f ( x ) f(x) f ( x ) 趋近于 1 1 1 ;当 x x x 趋近于负无穷大时,f ( x ) f(x) f ( x ) 趋近于 0 0 0 。
中心对称:逻辑函数在 x = 0 x=0 x = 0 处对称,即 f ( 0 ) = 0.5 f(0) = 0.5 f ( 0 ) = 0 . 5 。
平滑性:逻辑函数的曲线平滑,无跳跃点或不连续点。
根据全概率公式,我们可以轻松地通过样本属于正例的概率推出样本属于负例的概率:
决策边界
假设当 h θ ( x ) ≥ 0.5 h_\theta(x) \ge 0.5 h θ ( x ) ≥ 0 . 5 时,预测 y = 1 y = 1 y = 1 ;当 h θ ( x ) < 0.5 h_\theta(x) < 0.5 h θ ( x ) < 0 . 5 时,预测 y = 0 y = 0 y = 0 。根据逻辑函数的性质,当 z ≥ 0 z \ge 0 z ≥ 0 时,g ( z ) ≥ 0.5 g(z) \ge 0.5 g ( z ) ≥ 0 . 5 ,要使得 h θ ( x ) ≥ 0.5 h_\theta(x) \ge 0.5 h θ ( x ) ≥ 0 . 5 ,则要求 θ T x ≥ 0 \theta^T x \ge 0 θ T x ≥ 0 。同理,若 θ T x < 0 \theta^T x < 0 θ T x < 0 ,那么 h θ ( x ) < 0.5 h_\theta(x) < 0.5 h θ ( x ) < 0 . 5 ,则会预测 y = 0 y = 0 y = 0 。
通过上述分析,我们将 y y y 的预测转换成了 θ T x \theta^T x θ T x 值与 0 0 0 的大小比较。对于二维的情况, θ T x = 0 \theta^T x = 0 θ T x = 0 可以在平面上确定一条直线(曲线),这条直线(曲线)会将平面分成两个部分,其中一个部分中的点会被预测为正例,另外一个部分中的点会被预测为负例。这条直线(曲线)就是模型 h θ ( x ) h_\theta(x) h θ ( x ) 的决策边界 。
值得注意的是:决策边界是模型本身的性质,与数据集无关。数据集仅仅被用来优化模型。
损失函数
一般化地,将损失函数写成如下形式:
J ( θ ) = 1 m ∑ i = 1 m C o s t ( h θ ( x ( i ) ) , y ( i ) ) J(\theta) = \dfrac{1}{m}\sum\limits_{i=1}^m {\rm Cost}(h_\theta(x^{(i)}), y^{(i)})
J ( θ ) = m 1 i = 1 ∑ m C o s t ( h θ ( x ( i ) ) , y ( i ) )
对于线性回归,其损失函数为:
C o s t ( h θ ( x ) , y ) = 1 2 ( h θ ( x ) − y ) 2 {\rm Cost}(h_\theta(x), y) = \dfrac{1}{2}(h_\theta(x) - y)^2
C o s t ( h θ ( x ) , y ) = 2 1 ( h θ ( x ) − y ) 2
这就是平方差损失函数。但是,对于逻辑回归,如果使用平方差损失函数,会导致损失函数非凸,因此需要另外一个损失函数——对数损失函数:
C o s t ( h θ ( x ) , y ) = { − log ( h θ ( x ) ) , y = 1 − log ( 1 − h θ ( x ) ) , y = 0 {\rm Cost}(h_\theta(x), y) =
\begin{cases}
-\log(h_\theta(x)), & y = 1 \\
-\log(1 - h_\theta(x)), & y = 0
\end{cases}
C o s t ( h θ ( x ) , y ) = { − log ( h θ ( x ) ) , − log ( 1 − h θ ( x ) ) , y = 1 y = 0
对于 y = 1 y = 1 y = 1 的情况,如果输出的 h θ ( x ) = 1 h_\theta(x) = 1 h θ ( x ) = 1 ,那么损失函数的值为 0 0 0 ,而如果输出的 h θ ( x ) → 0 h_\theta(x) \to 0 h θ ( x ) → 0 ,那么损失函数的值会趋向于无穷。这对 y = 0 y = 0 y = 0 的情况也是类似的。
由于 y y y 只会为 0 0 0 或 1 1 1 ,因此可以将代价函数简化成如下形式:
C o s t ( h θ ( x ) , y ) = − y log ( h θ ( x ) ) − ( 1 − y ) log ( 1 − h θ ( x ) ) {\rm Cost}(h_\theta(x), y) = -y\log(h_\theta(x)) - (1-y)\log(1 - h_\theta(x))
C o s t ( h θ ( x ) , y ) = − y log ( h θ ( x ) ) − ( 1 − y ) log ( 1 − h θ ( x ) )
梯度下降
通过损失函数对 θ \theta θ 求偏导,可以得到梯度下降公式如下:
θ j : = θ j − α ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j - \alpha \sum\limits_{i=1}^m (h_\theta(x^{(i)}) - y^{(i)})x^{(i)}_j
θ j : = θ j − α i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i )
可以发现,这个梯度下降公式与线性回归的下降公式是一致的。但是由于模型的定义发生了变化,所以逻辑回归和线性回归本质上其实是不同的算法。
高级优化
除了梯度下降算法,还有一些其他的高级算法可以用来寻找最优的参数值。如共轭梯度、BFGS、L-BFGS 等。这些算法通常不需要手动确定学习率,并且比梯度下降更快。但是其不足之处在于:相较于梯度下降算法,这些算法会有亿点点复杂。
多分类问题:一对多
多分类问题是指样本不止两类的情况,即 y y y 可能为 2 , 3 , 4 , ⋯ 2, 3, 4, \cdots 2 , 3 , 4 , ⋯ 。例如判断天气时晴天、多云、下雨或者下雪。
多分类问题的一对多方法的思想是:假设一共有 n n n 个类别,训练 n n n 个二分类器,其中第 i i i 个分类器以第 i i i 类样本为正例,其他所有样本为负例,输出样本属于第 i i i 类的概率。即:
h θ ( i ) ( x ) = P ( y = i ∣ x ; θ ) ( i = 1 , 2 , 3 , ⋯ ) h^{(i)}_\theta(x) = P(y = i\ |\ x;\theta)\quad (i=1,2,3,\cdots)
h θ ( i ) ( x ) = P ( y = i ∣ x ; θ ) ( i = 1 , 2 , 3 , ⋯ )
对于一个新的样本 x x x ,将其输入到所有 n n n 个分类器中,取输出概率最大的那个分类器,作为 x x x 的所属类别。即:
max i h θ ( i ) ( x ) \max\limits_{i}h^{(i)}_\theta(x)
i max h θ ( i ) ( x )
第七章 正则化
过拟合问题
如果特征数量非常庞大,那么模型可能会很好地拟合训练集,但是难以泛化到其他的样本中去,这就是过拟合问题。与过拟合相对,如果模型并不能很好地拟合训练集,就被称作为欠拟合。
高偏差与高方差的概念:
偏差(Bias)是指模型对于训练数据的错误偏离程度。当模型具有高偏差时,意味着模型对于训练数据的拟合程度较低,即欠拟合。
方差(Variance)是指模型对于不同训练数据集的响应程度。当模型具有高方差时,意味着模型对于训练数据的拟合程度较高,但在处理新的、未见过的数据时表现较差,即过拟合。
为了解决过拟合问题,常常有以下两种方式:
减少特征的数量 :人工选择保留的特征,或者通过模型选择算法选择保留的特征。但是减少特征数量意味着丢失了一些用于解决问题的信息。
正则化 :保留所有的特征,但是让 θ \theta θ 的值处于一个很小的范围,这在有许多特征的问题中非常有效,每一个特征都对预测结果产生了一点点影响。
损失函数
正则化的思想在于通过在损失函数中加入对参数 θ \theta θ 的乘法项,以让 θ \theta θ 的值更小,更小的 θ \theta θ 值就意味着更“简单”的模型,也意味着更难发生过拟合。
因此,运用了正则化思想的损失函数如下式所示(假设参数数量为 n n n ):
J ( θ ) = 1 2 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ ∑ i = 1 n θ i 2 ] J(\theta) = \dfrac{1}{2m}\left[\sum\limits_{i=1}^m (h_\theta(x^{(i)} ) - y^{(i)})^2 + \lambda \sum\limits_{i=1}^n \theta^2_i\right]
J ( θ ) = 2 m 1 [ i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ i = 1 ∑ n θ i 2 ]
后一个循环的下标从 1 1 1 开始是因为一般不对 θ 0 \theta_0 θ 0 进行正则化,但实际上对 θ 0 \theta_0 θ 0 进行正则化也问题不大。
公式中的 λ \lambda λ 是正则化系数,用于控制模型损失和正则化损失的权重,以引导学习算法更关注数据的拟合还是模型的简化。如果 λ \lambda λ 被设置得过大,则可能导致以下后果:
算法设计得过于完美,把 λ \lambda λ 设置得很大并不会造成什么影响(一般来说是想 peach)。
算法不再能防止过拟合。
算法甚至可能导致欠拟合。
梯度可能很难下降。
线性回归中的正则化
线性回归的求解有梯度下降和正规方程两种解法,因此对这两种情况分别进行讨论。
对于梯度下降法,损失函数为:
J ( θ ) = 1 2 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ ∑ i = 1 n θ i 2 ] J(\theta) = \dfrac{1}{2m}\left[\sum\limits_{i=1}^m (h_\theta(x^{(i)} ) - y^{(i)})^2 + \lambda \sum\limits_{i=1}^n \theta^2_i\right]
J ( θ ) = 2 m 1 [ i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ i = 1 ∑ n θ i 2 ]
因此梯度下降公式为:
注意,分情况讨论的原因是一般不对 θ 0 \theta_0 θ 0 进行正则化,同时对下面的公式稍作变形,可以得到:
θ j : = θ j ( 1 − α λ m ) − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j(1 - \alpha\dfrac{\lambda}{m}) - \alpha \dfrac{1}{m}\sum\limits_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})x^{(i)}_j
θ j : = θ j ( 1 − α m λ ) − α m 1 i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i )
由于一般 α \alpha α 很小,而 m m m 很大,因此 1 − α λ m 1 - \alpha\dfrac{\lambda}{m} 1 − α m λ 会很接近于 1 1 1 。于是我们就可以看到加入正则化之后的梯度下降相当于每一次先稍微减小一下 θ \theta θ 的值,再进行常规的梯度下降,这与正则化想要减小参数值大小的思想是一致的。
对于正规方程法,最优 θ \theta θ 求解公式为:
θ = ( X T X + λ [ 0 1 1 ⋱ 1 ] ) − 1 X T y \theta = \left(X^TX + \lambda
\begin{bmatrix}
0 & \\
& 1 \\
& & 1 \\
& & & \ddots \\
& & & & 1
\end{bmatrix}
\right)^{-1}X^Ty θ = ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ X T X + λ ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ 0 1 1 ⋱ 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ ⎠ ⎟ ⎟ ⎟ ⎟ ⎟ ⎞ − 1 X T y
值得注意的是,在这个公式中,矩阵 X T X + λ [ 0 1 1 ⋱ 1 ] X^TX + \lambda\begin{bmatrix}0 & \\& 1 \\& & 1 \\& & & \ddots \\& & & & 1\end{bmatrix} X T X + λ ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ 0 1 1 ⋱ 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ 一定是可逆的。
逻辑回归中的正则化
在逻辑回归中,正则化的损失函数为:
J ( θ ) = − [ ∑ i = 1 m y ( i ) log ( h θ ( x ( i ) ) ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ i = 1 n θ j 2 J(\theta) = -\left[\sum\limits_{i=1}^m y^{(i)}\log(h_\theta(x^{(i)})) + (1-y^{(i)})\log(1 - h_\theta(x^{(i)}))\right] + \dfrac{\lambda}{2m}\sum\limits_{i=1}^n\theta^2_j
J ( θ ) = − [ i = 1 ∑ m y ( i ) log ( h θ ( x ( i ) ) ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ] + 2 m λ i = 1 ∑ n θ j 2
其梯度下降更新公式为:
可以看到,正则化的逻辑回归,其梯度下降公式与正则化线性回归的梯度下降公式是一样的。但是同样的:因为两种问题的模型在定义上就是不同的,所以本质上,这两种梯度下降是不一样的。
第八章 神经网络
非线性模型
在实际的机器学习问题中,特征的数量往往非常庞大,这导致我们需要非线性模型来解决问题。
假设原始特征数量为 n n n ,如果使用线性回归或逻辑回归算法,即使仅仅包含了所有的一次项特征和二次项特征,那么模型所考虑的特征数量是 Θ ( n 2 ) \Theta(n^2) Θ ( n 2 ) 级别的。大量的特征会导致模型过于复杂,而容易导致过拟合。而如果舍弃一些特征,就丢失了很多用于解决问题的信息。
这个时候,就需要引入新的算法,而神经网络 在学习复杂的非线性模型上被证明是一种好得多的算法。
神经元和大脑
神经系统科学家曾经做过一个有趣的实验:把耳朵到听觉皮层的神经切断,而将眼睛向大脑输入信号的神经接到听觉皮层上,这样视觉信号就会被传输到听觉皮层中。实验发现:在这样的情况下,听觉皮层能够学会“看”。这个实验被称作为神经重接实验。
神经重接实验告诉我们:大脑可以进行多种复杂的任务不是因为大脑中有各种各样不同的“程序”,而是因为大脑有一套学习算法,大脑通过这个算法可以学会各种各样数据的处理。因此,通过寻找一个类似于大脑学习算法的算法,将其运用在计算机上,我们的计算机就很大概率能够变得更加智能。这也导致了神经网络模型的出现。
其他的一些关于大脑学习能力的例子:
BrainPort 系统:在前额上戴上一个灰度摄像头,将灰度信号用一根线连接到舌头上安装的电极阵列上。通过这样的方式,可以让我们的舌头学会“看”东西。
人体回声定位:通过特殊的培训,可以让人们打响指,或者咂舌头,并学会解读从环境中反射回来的声波,从而避免撞到障碍物。
触觉皮带:将其戴在腰上,并将皮带上的蜂鸣器打开,那么只有朝北的那个蜂鸣器会发出声音,这可以让人拥有像鸟类一样的感知方向的能力。
如果在青蛙身上移植第三只眼睛,那么青蛙能够学会使用那只眼睛。
模型表示
大脑内的一个神经元会有若干树突用于接收信息,以及一个轴突用于传出信息。根据这样的结构,我们可以构造出如下的逻辑单元,我们一般将其称为神经元。
这个神经元接收输入 x 1 , x 2 , x 3 x_1, x_2, x_3 x 1 , x 2 , x 3 ,对其进行一些计算,最后输出 h θ ( x ) h_\theta(x) h θ ( x ) 。这里 h θ ( x ) = 1 1 + e − θ T x h_\theta(x) = \dfrac{1}{1 + e^{-\theta^Tx} } h θ ( x ) = 1 + e − θ T x 1 ,其中 x = [ x 0 x 1 x 2 x 3 ] x=\begin{bmatrix}x_0 \\ x_1 \\ x_2 \\ x_3\end{bmatrix} x = ⎣ ⎢ ⎢ ⎢ ⎡ x 0 x 1 x 2 x 3 ⎦ ⎥ ⎥ ⎥ ⎤ 是输入数据,θ = [ θ 0 θ 1 θ 2 θ 3 ] \theta=\begin{bmatrix}\theta_0 \\ \theta_1 \\ \theta_2 \\ \theta_3\end{bmatrix} θ = ⎣ ⎢ ⎢ ⎢ ⎡ θ 0 θ 1 θ 2 θ 3 ⎦ ⎥ ⎥ ⎥ ⎤ 是可训练参数。在实际应用过程中,一般还会输入偏置项 x 0 x_0 x 0 ,在图中为了方便,就未画出。
将若干个神经元连接起来,就能够得到一个神经网络:
为了表述方便,将这个网络从左至右依次称为第 1 1 1 、2 2 2 、3 3 3 层。用 a i ( j ) a^{(j)}_i a i ( j ) 表示第 j j j 层的第 i i i 个神经元的输出值,θ ( j ) \theta^{(j)} θ ( j ) 表示第 j + 1 j + 1 j + 1 层的神经元处理第 j j j 层神经元传过来的信号时的参数。
输入层、输出层、隐藏层的定义:
输入层 :一般将最左边的层称为输入层,因为这一层的输入是原始特征 x x x ,其只是起到一个传递 x x x 的作用,因此其输出值也是 x x x ,即可以认为:a ( 0 ) = x a^{(0)} = x a ( 0 ) = x 。
输出层 :一般将最右边的层称为输出层,因为这一层用于输出最终结果,其输出对应标签 y y y 。
隐藏层 :夹在输入层和输出层之间的层被称为隐藏层,隐藏层用于提取特征,中间层的输出不会在数据集中体现。
神经网络的计算方式如下式所示(假设前一层一共有 n n n 个特征):
a i ( j ) = g ( ∑ k = 0 n θ j − 1 , k ( j − 1 ) a k ( j − 1 ) ) a^{(j)}_i = g(\sum\limits_{k=0}^n\theta^{(j-1)}_{j-1,k}a^{(j-1)}_k)
a i ( j ) = g ( k = 0 ∑ n θ j − 1 , k ( j − 1 ) a k ( j − 1 ) )
表示为向量形式:
a ( j ) = g ( θ ( j − 1 ) a ( j − 1 ) ) a^{(j)} = g(\theta^{(j - 1)}a^{(j - 1)})
a ( j ) = g ( θ ( j − 1 ) a ( j − 1 ) )
这里的 g g g 代表 Sigmoid 函数,即 g ( x ) = 1 1 + e − x g(x) = \dfrac{1}{1 + e^{-x} } g ( x ) = 1 + e − x 1 。在上述的例子中,最终输出值 h θ ( x ) = a 1 ( 3 ) h_\theta(x) = a^{(3)}_1 h θ ( x ) = a 1 ( 3 ) 。
观察计算方式可以发现:如果第 j j j 层一共有 s j s_j s j 个神经元,第 j + 1 j + 1 j + 1 层一共有 s j + 1 s_{j + 1} s j + 1 个神经元,那么参数 θ ( j ) \theta^{(j)} θ ( j ) 的形状为:s j + 1 × ( s j + 1 ) s_{j + 1}\times (s_j + 1) s j + 1 × ( s j + 1 ) 。
特别地,输出层的计算方式如下:
h θ ( x ) = a ( 3 ) = g ( θ ( 2 ) a ( 2 ) ) h_\theta(x) = a^{(3)} = g(\theta^{(2)}a^{(2)})
h θ ( x ) = a ( 3 ) = g ( θ ( 2 ) a ( 2 ) )
观察输出层的计算公式可以发现,输出层相当于一个逻辑回归层,但是相较于传统的逻辑回归,输出层的逻辑回归使用的特征是隐藏层提取出来的高级特征,而不是原始特征,多层线性函数和激活函数的嵌套,给予了神经网络算法强大的拟合能力。
举个例子:可以很容易构造出进行与、或、非运算的神经网络。通过对这三种神经网络进行嵌套,可以构造出进行异或运算的神经网络。这样我们就通过线性运算和激活函数,拟合了一个复杂函数。具体嵌套方式如下式所示:
x 1 X N O R x 2 = ( x 1 A N D x 2 ) O R ( ( N O T x 1 ) A N D ( N O T x 2 ) ) x_1\ {\rm XNOR}\ x_2 =(x_1\ {\rm AND}\ x_2)\ {\rm OR}\ (({\rm NOT}\ x_1)\ {\rm AND}\ ({\rm NOT}\ x_2))
x 1 X N O R x 2 = ( x 1 A N D x 2 ) O R ( ( N O T x 1 ) A N D ( N O T x 2 ) )
多分类
使用神经网络解决多分类问题本质上是逻辑回归一对多方法的应用。具体地,假设一共有 4 4 4 个类别,那么就让输出层一共有 4 4 4 个神经元,每个神经元分别输出样本属于对应类别的概率。理想情况下,当样本属于第一类时,神经网络的输出为:h θ ( x ) ≈ [ 1 0 0 0 ] h_\theta(x)\approx \begin{bmatrix}1\\0\\0\\0\end{bmatrix} h θ ( x ) ≈ ⎣ ⎢ ⎢ ⎢ ⎡ 1 0 0 0 ⎦ ⎥ ⎥ ⎥ ⎤ ;当样本属于第二类时,神经网络的输出为:h θ ( x ) ≈ [ 0 1 0 0 ] h_\theta(x)\approx \begin{bmatrix}0\\1\\0\\0\end{bmatrix} h θ ( x ) ≈ ⎣ ⎢ ⎢ ⎢ ⎡ 0 1 0 0 ⎦ ⎥ ⎥ ⎥ ⎤ ;依此类推……
对于这样的算法,我们所构建的数据集应当满足如下形式:( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , ⋯ , ( x ( m ) , y ( m ) ) (x^{(1)},y^{(1)}), (x^{(2)},y^{(2)}), \cdots, (x^{(m)},y^{(m)}) ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , ⋯ , ( x ( m ) , y ( m ) ) ,其中 y ( i ) y^{(i)} y ( i ) 是 [ 1 0 0 0 ] \begin{bmatrix}1\\0\\0\\0\end{bmatrix} ⎣ ⎢ ⎢ ⎢ ⎡ 1 0 0 0 ⎦ ⎥ ⎥ ⎥ ⎤ 、[ 0 1 0 0 ] \begin{bmatrix}0\\1\\0\\0\end{bmatrix} ⎣ ⎢ ⎢ ⎢ ⎡ 0 1 0 0 ⎦ ⎥ ⎥ ⎥ ⎤ 、[ 0 0 1 0 ] \begin{bmatrix}0\\0\\1\\0\end{bmatrix} ⎣ ⎢ ⎢ ⎢ ⎡ 0 0 1 0 ⎦ ⎥ ⎥ ⎥ ⎤ 、[ 0 0 0 1 ] \begin{bmatrix}0\\0\\0\\1\end{bmatrix} ⎣ ⎢ ⎢ ⎢ ⎡ 0 0 0 1 ⎦ ⎥ ⎥ ⎥ ⎤ 四者之一。
第九章 神经网络的学习
损失函数
假设神经网络一共有 L L L 层,第 l l l 层的神经元个数(不包括偏置项)为 s l s_l s l 。样本的类别一共有 K K K 个,特别地,对于二分类问题,K = 1 K=1 K = 1 ,因为二分类问题只需要使用一个分类器即可。
于是可以得到:h θ ( x ) ∈ R K h_\theta(x) \in {\mathbb R}^K h θ ( x ) ∈ R K ,令 ( h θ ( x ) ) i (h_\theta(x))_i ( h θ ( x ) ) i 表示神经网络的第 i i i 个输出。那么神经网络的损失函数如下式所示:
J ( θ ) = − 1 m [ ∑ i = 1 m ∑ k = 1 K y ( i ) log ( h θ ( x ( i ) ) k ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) k ) ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( θ j i ( l ) ) 2 J(\theta) = -\dfrac{1}{m}\left[\sum\limits_{i=1}^m\sum\limits_{k=1}^K y^{(i)}\log(h_\theta(x^{(i)})_k) + (1 -y^{(i)})\log(1 - h_\theta(x^{(i)})_k)\right] + \dfrac{\lambda}{2m}\sum\limits_{l=1}^{L-1}\sum\limits_{i=1}^{s_l}\sum\limits_{j=1}^{s_{l+1} }(\theta^{(l)}_{ji})^2
J ( θ ) = − m 1 [ i = 1 ∑ m k = 1 ∑ K y ( i ) log ( h θ ( x ( i ) ) k ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) k ) ] + 2 m λ l = 1 ∑ L − 1 i = 1 ∑ s l j = 1 ∑ s l + 1 ( θ j i ( l ) ) 2
公式的前半段是用于拟合数据的损失,后半段是用于正则化的损失。
反向传播
定义 δ j ( l ) \delta^{(l)}_j δ j ( l ) 表示第 l l l 层的第 j j j 个神经元的“误差”。对于一个四层的神经网络,其 δ \delta δ 计算方式如下:
这里的 g ′ ( x ) g^{'}(x) g ′ ( x ) 是 Sigmoid 函数在 x x x 处的导数。注意,我们并不需要计算 δ ( 1 ) \delta^{(1)} δ ( 1 ) ,因为第一层(输入层)的神经元只是简单地把输入传递给下一层,而不涉及到什么计算。
通过上述计算,我们就可以用如下公式计算每一个参数的梯度:
∂ J ∂ θ i j ( l ) = a j ( l ) δ i l + 1 \dfrac{\partial J}{\partial \theta^{(l)}_{ij} } = a^{(l)}_j\delta^{l + 1}_i
∂ θ i j ( l ) ∂ J = a j ( l ) δ i l + 1
写成向量化的形式为:
∂ J ∂ θ ( l ) = δ l + 1 ( a ( l ) ) T \dfrac{\partial J}{\partial \theta^{(l)} } = \delta^{l + 1}(a^{(l)})^T
∂ θ ( l ) ∂ J = δ l + 1 ( a ( l ) ) T
具体证明过程可以参考 jumper17 的博客 ,形象化理解可以参考李宏毅老师的视频 。
更深刻的理解:
根据链式求导法则:∂ J ∂ θ = ∂ J ∂ θ a ∂ θ a ∂ θ \dfrac{\partial J}{\partial \theta} = \dfrac{\partial J}{\partial \theta a}\dfrac{\partial \theta a}{\partial \theta} ∂ θ ∂ J = ∂ θ a ∂ J ∂ θ ∂ θ a 。而 ∂ θ a ∂ θ = a \dfrac{\partial \theta a}{\partial \theta} = a ∂ θ ∂ θ a = a 。所以,实际上可以将 δ j ( l ) \delta^{(l)}_j δ j ( l ) 视作损失函数 C o s t ( i ) {\rm Cost}(i) C o s t ( i ) 对 θ j ( l − 1 ) a ( l − 1 ) \theta^{(l-1)}_ja^{(l-1)} θ j ( l − 1 ) a ( l − 1 ) 的导数,即:
δ j ( l ) = ∂ ∂ ( θ j ( l − 1 ) a ( l − 1 ) ) C o s t ( i ) \delta^{(l)}_j = \dfrac{\partial }{\partial(\theta^{(l-1)}_ja^{(l-1)})}{\rm Cost}(i)
δ j ( l ) = ∂ ( θ j ( l − 1 ) a ( l − 1 ) ) ∂ C o s t ( i )
而根据链式求导法则,δ j ( l ) \delta^{(l)}_j δ j ( l ) 又可以根据下一层的 δ ( l + 1 ) \delta^{(l+1)} δ ( l + 1 ) 计算出来。这是一个递归的过程,可以从后往前将递归转换为递推,就是反向传播算法了。
对于 batch 训练,可以对于每个样本算出其 δ \delta δ ,再累加求和。即样本的总体“误差” Δ \Delta Δ 按如下公式计算:
Δ ( l ) : = ∑ δ l + 1 ( a ( l ) ) T \Delta^{(l)} := \sum\delta^{l + 1}(a^{(l)})^T
Δ ( l ) : = ∑ δ l + 1 ( a ( l ) ) T
最后每个参数的导数为:
∂ J ( θ ) ∂ θ i j l = { 1 m Δ i j l + λ m θ i j ( l ) , j ≠ 0 1 m Δ i j l , j = 0 \dfrac{\partial J(\theta)}{\partial \theta^{l}_{ij} } =
\begin{cases}
\dfrac{1}{m} \Delta^{l}_{ij} + \dfrac{\lambda}{m}\theta^{(l)}_{ij}, &j\neq 0 \\
\\
\dfrac{1}{m} \Delta^{l}_{ij}, &j=0
\end{cases}
∂ θ i j l ∂ J ( θ ) = ⎩ ⎪ ⎪ ⎪ ⎪ ⎨ ⎪ ⎪ ⎪ ⎪ ⎧ m 1 Δ i j l + m λ θ i j ( l ) , m 1 Δ i j l , j = 0 j = 0
梯度检验
在实现反向传播算法的过程中,可能会出现一些 bug ,这时候就需要通过梯度检验来确保反向传播算法正确计算梯度。
一般使用双侧差分的方式进行梯度检验,即:
d d θ J ( θ ) ≈ J ( θ + ϵ ) − J ( θ − ϵ ) 2 ϵ \dfrac{ {\rm d} }{ {\rm d}\theta}J(\theta) \approx \dfrac{J(\theta + \epsilon) - J(\theta - \epsilon) }{2\epsilon}
d θ d J ( θ ) ≈ 2 ϵ J ( θ + ϵ ) − J ( θ − ϵ )
这里 ϵ \epsilon ϵ 是一个很小很小的值,如 1 0 − 4 10^{-4} 1 0 − 4 。双侧差分意味着在 θ \theta θ 的两边都增加一个 ϵ \epsilon ϵ ,单侧差分则只会在某一侧增加,一般来说,双侧差分更加准确。
如果 θ \theta θ 是一个向量,那么就对每一个分量求偏导。具体地,假设 θ = [ θ 1 , θ 2 , ⋯ , θ n ] \theta = [\theta_1, \theta_2, \cdots, \theta_n] θ = [ θ 1 , θ 2 , ⋯ , θ n ] ,那么分别计算:
最后,在训练时一定不要执行梯度检验,因为梯度检验的效率很低。在训练时应当使用反向传播算法。
随机初始化
在开始训练之前,需要为网络中的参数指定初始值。如果将所有的参数都设置为同一个值(比如 0 0 0 ),那么同一层的神经元的输出都会相同,反向传播的梯度也会相同,这导致同一层的所有神经元学习到的特征是相同的,从而极大地减弱了神经网络的学习能力。因此,在进行参数初始化时,要利用随机初始化将参数 θ \theta θ 随机到 [ − ϵ , ϵ ] [-\epsilon, \epsilon] [ − ϵ , ϵ ] 的范围内,即 − ϵ ≤ θ ≤ ϵ -\epsilon \le \theta \le \epsilon − ϵ ≤ θ ≤ ϵ 。一个可行的初始化方式为:
θ = R a n d o m ( 0 , 1 ) × 2 ϵ − ϵ \theta = {\rm Random}(0, 1) \times 2\epsilon - \epsilon
θ = R a n d o m ( 0 , 1 ) × 2 ϵ − ϵ
这里的 R a n d o m ( 0 , 1 ) {\rm Random}(0, 1) R a n d o m ( 0 , 1 ) 是指 [ 0 , 1 ] [0, 1] [ 0 , 1 ] 之间的随机数。
利用神经网络解决问题的一般步骤
首先需要确定网络架构(输入层、隐藏层、输出层及其之间的连接方式)。其中输入层神经元数量和特征数量相同,输出层神经元数量和类别总数相同(对于二分类问题可以只有一个输出)。对于隐藏层:一般默认只有一层隐藏层,如果有多层隐藏层,那么不同层的神经元数量应该相同。当然,在深度神经网络越来越流行的情况下,这个默认的准则已经效果越来越小了。
确定好网络架构之后,就是训练神经网络了。训练神经网络一般遵循以下六个步骤:
初始化神经网络参数。
实现前向传播方法计算 h θ ( x ) h_\theta(x) h θ ( x ) 。
实现损失函数 J ( θ ) J(\theta) J ( θ ) 的计算。
实现反向传播算法计算偏导数 ∂ ∂ θ j k ( l ) J ( θ ) \dfrac{\partial}{\partial\theta^{(l)}_{jk} }J(\theta) ∂ θ j k ( l ) ∂ J ( θ ) 。
进行梯度检验,以确保反向传播梯度计算的正确性。
通过反向传播算法进行梯度下降或者使用其他高级优化算法优化网络参数。
第十章 机器学习算法应用技巧
模型评估
为了评估模型,通常将数据集划分成训练集和测试集,先在训练集上训练模型,再在测试集上计算测试集误差。度量误差的方式可以是损失函数,或者准确率。
模型选择(为什么需要验证集)
有的时候我们并不清除要用怎样一个模型(超参数)以拟合数据。因此在训练与测试之后,需要进行参数调优。如果我们使用训练集训练模型,再用测试集计算测试集误差,以该误差作为判断模型泛化能力的标准。那么在参数调优的过程中,相当于把测试集当作训练集,用于拟合超参数。这样得到的超参数是不能很好地表现模型的泛化能力的。因此一般要把数据集分为三部分:训练集、验证集、测试集。训练集用于训练模型,验证集用于参数调优,测试集用于评估模型泛化能力。
偏差、方差和正则化
当模型效果不好时,往往是因为其面临着高偏差(欠拟合)或者高方差(过拟合)的问题。这两种问题分别有以下特征:
高偏差(欠拟合)表现为训练集误差和验证集误差都很高。
高方差(过拟合)表现为训练集误差很低,但是验证集误差很高。
一般会使用正则化来缓解过拟合问题。当使用正则化时,训练的损失函数为:模型误差 + + + 正则化项。但是在评估训练集误差和验证集误差时,一般会将正则化项删除 。正则化系数 λ \lambda λ 对误差的影响如下:
当 λ \lambda λ 较小时,相当于模型没有正则化,此时模型会倾向于过拟合,即训练集误差很低,但是验证集误差很高。
当 λ \lambda λ 较大时,相当于正则化过度,此时模型会倾向于欠拟合,即训练集误差和验证集误差都很高。
学习曲线
在训练的过程中,人为控制训练集的大小,画出训练集误差和验证集误差随着训练集大小变化的曲线,有助于判断模型处于欠拟合状态还是过拟合状态。
一般来说,随着训练集的增大,训练集误差会不断增大,而验证集误差会不断减小,最后收敛到相似的适中的值。
当模拟欠拟合时,训练集误差和验证集误差都会收敛到很高的值,并且在一定数据集大小之后,即使数据集大小再增加,验证集误差也不会减小太多(几乎呈一条水平直线)。因此增加数据量并不能解决欠拟合问题。
当模型过拟合时,训练集误差会维持在一个较低的水平,而验证集误差会维持在一个较高的水平,两者差距较大。但是随着训练集大小的增加,训练集误差总是会上升,验证集误差总是会下降,最后收敛到相似的合适值。因此增加数据量有助于缓解过拟合问题。
过拟合(欠拟合)问题的一些解决方法
解决过拟合问题的方法:增加训练集大小,使用更少的特征,调大正则化参数 λ \lambda λ ……
解决欠拟合问题的方法:使用更多的特征、增加多项式特征、调小正则化参数 λ \lambda λ ……
另外,使用更小的神经网络会有更少的参数,更容易欠拟合,但是计算起来速度很快;使用更大的神经网络会有更多的参数,更容易过拟合,而且计算起来速度偏慢。但是总体上来说,大的神经网络性能要优于小的神经网络。
第十一章 机器学习系统设计
误差分析
当我们设计一个机器学习系统时,推荐的实现步骤如下:
首先实现一个很简单的算法,并再验证集上进行测试。
画出学习曲线,以确定是否需要更多的数据或者特征。
进行误差分析,人工检查算法分类出错的样本,以找出算法出错的趋势。如分析哪一类的样本经常被误分类,被误分类的样本会有什么样的特征。
同时,可量化的评价指标也很重要。通过引入可量化的评价指标,可以很直观地评价两种算法的优劣,从而方便尝试各种想法。
非对称性分类的评价指标
在一些正类和负类样本数量差距非常大的环境(如只有 0.5 % 0.5\% 0 . 5 % 的人患有癌症)下,分类准确率不一定能很好反应处算法的性能。比如一个神经网络算法拥有 99 % 99\% 9 9 % 的准确率,但是如果将所有人预测为没有癌症,这个策略的准确率为 99.5 % 99.5\% 9 9 . 5 % 。后者在指标上比前者更优,但是显然不合里。因此需要更加准确的指标。一些常用的指标有精确率和召回率:
精确率(Precision) :表示在所有预测为正类的样本中,真正为正类的样本的比例。
召回率(Recall) :表示在所有真正为正类的样本中,预测为正类的样本的比例。
在非对称性分类中,一般将样本较少的类视为正类。
通俗地讲,精确率是判断模型预测准不准的指标,又被称为查准率;召回率是判断模型预测全不全的指标,又被称为查全率。
精确率和召回率的权衡
一般来讲,较高的精确率会带来较低的召回率;较高的召回率会带来较低的精确率(例如二分类问题中,阈值的设置)。因此需要权衡精确率和召回率带来的影响,以判断模型的表现。有以下两种计算方式:
取平均 :P r e c i s i o n + R e c a l l 2 \dfrac{ {\rm Precision} + {\rm Recall} }{2} 2 P r e c i s i o n + R e c a l l ,这个方法以精确率和召回率的算数平均值作为最终指标,其实并不好,因为算术平均值受极端值影响太大。
F 1 F_1 F 1 分数 :2 P r e c i s i o n × R e c a l l P r e c i s i o n + R e c a l l 2\dfrac{ {\rm Precision} \times {\rm Recall} }{ {\rm Precision} + {\rm Recall} } 2 P r e c i s i o n + R e c a l l P r e c i s i o n × R e c a l l ,这个方法以精确率和召回率的调和平均值作为最终指标。调和平均值受到较小值的影响更大,因为小数的倒数较大,对整体平均值的贡献更大,最终值也会更低。调和平均值考虑到了数值之间的相对关系,是更加合理的评价指标。
机器学习中的数据
在保证数据中的特征 x x x 提供了足够多的信息以预测 y y y 的情况下,增大数据量能够有效地提升机器学习算法的性能。一个判断信息是否足够的有效方法是判断给定相应的 x x x ,人类专家能否判断出 y y y 。
模型与数据的关系:
模型越复杂,偏差越低,越不容易欠拟合。
数据越多,方差越低,越不容易过拟合。
第十二章 支持向量机
优化目标
支持向量机模型的假设为:
h θ ( x ) = { 1 , θ T x ≥ 0 0 , e l s e h_\theta(x) =
\begin{cases}
1, &\theta^Tx \ge 0 \\
0, &{\rm else}
\end{cases}
h θ ( x ) = { 1 , 0 , θ T x ≥ 0 e l s e
假设当训练集中 y ( i ) = 1 y^{(i)}=1 y ( i ) = 1 时,支持向量机的损失函数为 c o s t 1 ( θ T x ( i ) ) {\rm cost}_1(\theta^Tx^{(i)}) c o s t 1 ( θ T x ( i ) ) ;当训练集中 y ( i ) = 0 y^{(i)}=0 y ( i ) = 0 时,支持向量机的损失函数为:c o s t 0 ( θ T x ( i ) ) {\rm cost}_0(\theta^Tx^{(i)}) c o s t 0 ( θ T x ( i ) ) ,那么支持向量机在训练过程中最小化的损失函数为:
min θ C ∑ i = 1 m [ y ( i ) c o s t 1 ( θ T x ( i ) ) + ( 1 − y ( i ) ) c o s t 0 ( θ T x ( i ) ) ] + 1 2 ∑ j = 1 n θ j 2 \min\limits_\theta C\sum\limits_{i=1}^m\left[y^{(i)}{\rm cost}_1(\theta^Tx^{(i)})+(1-y^{(i)}){\rm cost}_0(\theta^Tx^{(i)})\right] + \dfrac{1}{2}\sum\limits_
{j=1}^n \theta_j^2 θ min C i = 1 ∑ m [ y ( i ) c o s t 1 ( θ T x ( i ) ) + ( 1 − y ( i ) ) c o s t 0 ( θ T x ( i ) ) ] + 2 1 j = 1 ∑ n θ j 2
最大间隔及其数学原理
为了简化讨论,假设支持向量机的损失函数为:
min θ 1 2 ∑ j = 0 n θ j 2 = 1 2 ∣ ∣ θ ∣ ∣ 2 \min\limits_\theta\dfrac{1}{2}\sum\limits_{j=0}^n\theta_j^2 = \dfrac{1}{2}||\theta||^2
θ min 2 1 j = 0 ∑ n θ j 2 = 2 1 ∣ ∣ θ ∣ ∣ 2
这里的 ∣ ∣ θ ∣ ∣ ||\theta|| ∣ ∣ θ ∣ ∣ 表示的时向量 θ \theta θ 的第二范数,即 ∑ j = 0 n θ j 2 \sqrt{\sum\limits_{j=0}^n\theta_j^2} j = 0 ∑ n θ j 2 ,也即向量 θ \theta θ 的长度(模)。
不失一般性地,讨论支持向量机对正类样本的预测。在正类样本(y ( i ) = 1 y^{(i)}=1 y ( i ) = 1 )上,我们希望 θ T x ( i ) ≥ 1 \theta^Tx^{(i)} \ge 1 θ T x ( i ) ≥ 1 。假设向量 x x x 和向量 θ \theta θ 之间的夹角为 α \alpha α ,向量 x x x 在向量 θ \theta θ 上的投影长度为 p = ∣ ∣ x ∣ ∣ cos α p = ||x||\cos \alpha p = ∣ ∣ x ∣ ∣ cos α ,那么有以下推导:
θ T x ( i ) = ∣ ∣ θ ∣ ∣ ⋅ ∣ ∣ x ( i ) ∣ ∣ cos α = ∣ ∣ θ ∣ ∣ ⋅ p \theta^Tx^{(i)} = ||\theta||\cdot||x^{(i)}||\cos \alpha = ||\theta|| \cdot p
θ T x ( i ) = ∣ ∣ θ ∣ ∣ ⋅ ∣ ∣ x ( i ) ∣ ∣ cos α = ∣ ∣ θ ∣ ∣ ⋅ p
因此:要同时使得 θ T x ( i ) \theta^Tx^{(i)} θ T x ( i ) 尽可能大,并且 ∣ ∣ θ ∣ ∣ ||\theta|| ∣ ∣ θ ∣ ∣ 尽可能小,就要求 p p p 尽可能大。p p p 尽可能大意味着向量 x x x 在向量 θ \theta θ 上的投影尽可能长,即离分类平面尽可能远(向量 θ \theta θ 是分类平面的法向量)。这就是支持向量机大间隔分类的由来。
核函数
对于一些线性不可分的数据集,可以为支持向量机手动添加高次项来进行非线性的拟合。当然也可以通过核函数来选取特征。具体地,假设平面上已经有了三个特殊点 l ( 1 ) , l ( 2 ) , l ( 3 ) l^{(1)}, l^{(2)}, l^{(3)} l ( 1 ) , l ( 2 ) , l ( 3 ) ,那么可以将样本点和这三个特殊点的距离作为特征,输入到支持向量机中,具体公式如下:
f i = s i m i l a r i t y ( x , l ( i ) ) = exp ( − ∣ ∣ x − l ( i ) ∣ ∣ 2 2 σ 2 ) f_i = {\rm similarity}(x, l^{(i)}) = \exp \left(-\dfrac{||x - l^{(i)}||^2}{2\sigma^2}\right)
f i = s i m i l a r i t y ( x , l ( i ) ) = exp ( − 2 σ 2 ∣ ∣ x − l ( i ) ∣ ∣ 2 )
在这里,我们将特征 f i f_i f i 描述为点 x x x 与特殊点 l ( i ) l^{(i)} l ( i ) 的相似度,这个相似度通过 x x x 与 l ( i ) l^{(i)} l ( i ) 之间的距离来描述。σ \sigma σ 是一个参数,这个参数可以调节模型的平滑性和拟合能力,σ 2 \sigma^2 σ 2 越大,模型越平滑,拟合能力越弱。这个核函数被称作为高斯核函数 。
对于 f i f_i f i 的输出:由于对距离取了负数,并且套上了一个指数函数,当 x x x 与 l ( i ) l^{(i)} l ( i ) 相距较近时,f i f_i f i 的输出值接近为 1 1 1 ;反之,当 x x x 与 l ( i ) l^{(i)} l ( i ) 相距较远时,f i f_i f i 的输出值接近为 0 0 0 。
最后的支持向量机模型如下:
h θ ( x ) = { 1 , θ 0 + ∑ i = 1 n θ i f i ≥ 0 0 , e l s e h_\theta(x) =
\begin{cases}
1, & \theta_0 + \sum\limits_{i=1}^n \theta_if_i \ge 0 \\
0, & {\rm else}
\end{cases}
h θ ( x ) = ⎩ ⎪ ⎨ ⎪ ⎧ 1 , 0 , θ 0 + i = 1 ∑ n θ i f i ≥ 0 e l s e
这样,模型会在样本接近一些特殊点时将其分类为正例,在样本远离一些特殊点时将其分类为负例。于是我们就得到了一个由选取的特殊点确定的非线性边界。
一个较为常用的特殊点选取方法为:将训练集中的样本点作为特殊点(可以是所有样本点)。
在训练带有核函数的支持向量机时,其损失函数为:
min θ C ∑ i = 1 m [ y ( i ) c o s t 1 ( θ T f ( i ) ) + ( 1 − y ( i ) ) c o s t 0 ( θ T f ( i ) ) ] + 1 2 ∑ j = 1 n θ j 2 \min\limits_\theta C\sum\limits_{i=1}^m\left[y^{(i)}{\rm cost}_1(\theta^Tf^{(i)})+(1-y^{(i)}){\rm cost}_0(\theta^Tf^{(i)})\right] + \dfrac{1}{2}\sum\limits_
{j=1}^n \theta_j^2 θ min C i = 1 ∑ m [ y ( i ) c o s t 1 ( θ T f ( i ) ) + ( 1 − y ( i ) ) c o s t 0 ( θ T f ( i ) ) ] + 2 1 j = 1 ∑ n θ j 2
这里 C C C 是损失系数,用于控制拟合损失在损失函数中所占的权重大小(相当于 1 λ \dfrac{1}{\lambda} λ 1 )。C C C 越大,模型越容易过拟合;C C C 越小,模型越容易欠拟合。
使用技巧
在使用支持向量机时,首先需要确定损失系数 C C C 以及所使用的核函数。常用的核函数有线性核函数(相当于没有使用核函数)和高斯核函数(需要确定 σ \sigma σ ),也有一些其他的核函数可供选择,如多项式核函数(一般形式为 ( x T l + a ) b (x^Tl + a)^b ( x T l + a ) b ,其中 a a a 和 b b b 是常数)、字符串核函数,卡方核函数、直方相交核函数等。
值得注意的是:在使用高斯核函数之前一定要进行归一化 !否则会出现某些特征贡献了绝大部分损失,从而导致模型无法平等地考虑所有特征的情况。
对于多分类问题:可以训练多个支持向量机,使用一对多的方法完成多分类问题。
最后关于模型的选择问题,假设 n n n 是特征数量,m m m 是训练样本数量,那么:
当 n n n 远大于 m m m 时,一般使用逻辑回归,或者不带核函数的支持向量机。
当 n n n 很小(1 ∼ 1000 1\sim 1000 1 ∼ 1 0 0 0 ),m m m 不大不小(10 ∼ 10000 10\sim 10000 1 0 ∼ 1 0 0 0 0 )时,一般使用高斯核的支持向量机。
当 n n n 很小,m m m 很大时,一般需要增加特征数量,再使用逻辑回归或者不带核函数的支持向量机。
对于神经网络,神经网络在各种情况下都能表现得很好,但是训练很慢。
第十三章 聚类
无监督学习
在监督学习中,训练集中的样本是有标签的,即训练集的形式为:{ ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , ⋯ , ( x ( m ) , y ( m ) ) } \{(x^{(1)}, y^{(1)}),(x^{(2)}, y^{(2)}),\cdots,(x^{(m)}, y^{(m)})\} { ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , ⋯ , ( x ( m ) , y ( m ) ) } 。但是,对于无监督学习,训练集中的样本是没有标签的,其形式为:{ x ( 1 ) , x ( 2 ) , x ( 3 ) , ⋯ , x ( m ) } \{x^{(1)},x^{(2)},x^{(3)},\cdots,x^{(m)}\} { x ( 1 ) , x ( 2 ) , x ( 3 ) , ⋯ , x ( m ) } ,我们希望学习算法在这一堆没有标签的数据中找到一些规律,发掘数据的内在结构。
K-Means 算法
K-Means 算法是最常用的聚类算法之一。首先,K-Means 算法会在平面上随机 K K K 个聚类中心 μ 1 , μ 2 , ⋯ , μ k \mu_1, \mu_2,\cdots, \mu_k μ 1 , μ 2 , ⋯ , μ k ,接下来反复执行以下两步,直到聚类中心位置不再发生变化:
对于每一个样本,计算出与其相距最近的聚类中心 k k k ,并将该样本划分为第 k k k 类,即:
c ( i ) = min k ∣ ∣ x ( i ) − μ k ∣ ∣ 2 c^{(i)} = \min\limits_k ||x^{(i)} - \mu_k||^2
c ( i ) = k min ∣ ∣ x ( i ) − μ k ∣ ∣ 2
对于每一类,将其聚类中心移动至所有属于这一类的样本的中心处,即:
μ k = ∑ c ( i ) = k x ( i ) ∑ c ( i ) = k 1 \mu_k = \dfrac{\sum\limits_{c^{(i)} = k}x^{(i)}}{\sum\limits_{c^{(i)} = k}1}
μ k = c ( i ) = k ∑ 1 c ( i ) = k ∑ x ( i )
优化目标
K-Means 算法的优化目标为最小化组内距离之和,因此其损失函数如下:
min c ( 1 ) , ⋯ , c ( m ) , μ 1 , ⋯ , μ k J ( c ( 1 ) , ⋯ , c ( m ) , μ 1 , ⋯ , μ k ) = 1 m ∑ i = 1 m ∣ ∣ x ( i ) − μ c ( i ) ∣ ∣ 2 \min\limits_{c^{(1)}, \cdots, c^{(m)}, \mu_1, \cdots, \mu_k} J(c^{(1)}, \cdots, c^{(m)}, \mu_1, \cdots, \mu_k) = \dfrac{1}{m}\sum\limits_{i=1}^m ||x^{(i)} - \mu_{c^{(i)}}||^2
c ( 1 ) , ⋯ , c ( m ) , μ 1 , ⋯ , μ k min J ( c ( 1 ) , ⋯ , c ( m ) , μ 1 , ⋯ , μ k ) = m 1 i = 1 ∑ m ∣ ∣ x ( i ) − μ c ( i ) ∣ ∣ 2
在数学上可以证明,K-Means 算法第一步对 c ( i ) c^{(i)} c ( i ) 的调整以及第二步对 μ k \mu_k μ k 的调整都可以使得损失函数的值变小。因此最后 K-Means 算法会收敛到一个最优解。
聚类中心的初始化
相较于纯随机的初始化,为了保证初始化的聚类中心都是有意义的(有的时候可能有一个聚类中心离所有点都很远),一般会随机使用训练集中的样本点作为初始聚类中心。这样往往会得到不错的效果。
但是即使是随机使用样本点,也无法避免局部最优的问题。在这个情况下,可以通过多次运行 K-Means 算法取最优来找到一个尽可能优的聚类结果。这个方法在聚类数量较少时(K = 2 ∼ 10 K=2\sim 10 K = 2 ∼ 1 0 )时比较有效,但是在聚类数量较多时效果就不明显了。
聚类数量的选取
聚类数量的选取是一个比较主观的问题,一般是人们利用自己的经验手动调整。
可以通过“肘部法则”来判断聚类数量,即画出损失函数值随聚类数量变化的曲线,如果在一个点之前,损失函数下降很快,但是在那个点之后,损失函数下降很慢,那么这个点往往就会是最适合的聚类数量。但是更多情况是损失函数平滑下降,这个时候就无法判断“肘部”的位置。
另外一种方法是根据聚类的目的判断聚类的数量。例如:如果需要将服装市场根据尺码细分为 S、M、L 三个市场,那么聚类数量选择为 3 是最合适的。
第十四章 降维
降维的目的
降维主要有以下两个目的:
数据压缩 :将数据从高维压到低维,可以降低数据所需的储存空间,还可以让一些学习算法具有更快的运行速度。
数据可视化 :高维数据难以可视化,如果可以将其压缩至 2 ∼ 3 2\sim 3 2 ∼ 3 维,就可以帮助我们进行可视化。
值得注意的是:降维之后的特征一般不具有直接的物理意义,而是多个原始特征的融合,因此为了清晰地描述降维之后的特征,需要弄清楚这些特征大致描述了些什么。
主成分分析(PCA)
主成分分析算法(Principal Component Analysis,PCA)所描述的问题如下:假设数据的原始维度为 n n n 维,需要将其降至 k k k 维,那么就要找出 k k k 个向量 u ( 1 ) , u ( 2 ) , ⋯ , u ( k ) u^{(1)}, u^{(2)}, \cdots, u^{(k)} u ( 1 ) , u ( 2 ) , ⋯ , u ( k ) ,这 k k k 个向量确定了一个 k k k 维空间,将原空间的特征点投影至 k k k 维空间之后,会产生一个投影误差(特征点到 k k k 维空间的距离)。PCA 所做的事情就是最小化投影误差。
PCA 与线性回归的区别:
PCA 是通过距离来计算投影误差;而线性回归是通过计算预测值与真实值的插值来计算误差。
PCA 将所有特征都同等对待,没有标签;而线性回归是利用一些特征去预测一个标签。
因此,PCA 不是线性回归 !
假设一共有 m m m 个样本,n n n 维特征,特征矩阵 X ∈ R n × m X\in {\mathbb R}^{n\times m} X ∈ R n × m ,那么 PCA 算法的步骤如下:
对数据进行归一化和均值标准化处理。
均值标准化:先计算出每个特征的平均值 μ j = 1 m ∑ i = 1 m x j ( i ) \mu_j = \dfrac{1}{m}\sum\limits_{i=1}^m x^{(i)}_j μ j = m 1 i = 1 ∑ m x j ( i ) ,再令每个 x j ( i ) = x j ( i ) − μ j x^{(i)}_j = x^{(i)}_j - \mu_j x j ( i ) = x j ( i ) − μ j 。这样就可以保证每个特征的平均值都是 0 0 0 。
计算特征之间的协方差矩阵 Σ = 1 m X X T \Sigma = \dfrac{1}{m} XX^T Σ = m 1 X X T 。这样 Σ \Sigma Σ 是一个 n × n n\times n n × n 的矩阵,第 i i i 行第 j j j 列表示了特征 i i i 与特征 j j j 的协方差。
对协方差矩阵进行奇异值分解:[ U , S , V ] = S V D ( Σ ) [U, S, V] = SVD(\Sigma) [ U , S , V ] = S V D ( Σ ) 。
取矩阵 U U U 的前 k k k 个列向量,作为确定 k k k 维空间的向量,即 U r e d u c e ∈ R n × k U_{\rm reduce} \in {\mathbb R}^{n\times k} U r e d u c e ∈ R n × k 。
计算原始特征在 k k k 维空间下的投影 z = U r e d u c e T X z = U_{\rm reduce}^TX z = U r e d u c e T X ,最后得到的 z z z 是一个 k × m k\times m k × m 的矩阵,恰好表示 m m m 个样本在 k k k 维空间里的投影。
主成分数量选择
定义平均平方投影误差为所有向量到投影空间距离平方的平均值:1 m ∑ i = 1 m ∣ ∣ x ( i ) − x a p p r o x ( i ) ∣ ∣ 2 \dfrac{1}{m}\sum\limits_{i=1}^m ||x^{(i)} - x^{(i)}_{\rm approx}||^2 m 1 i = 1 ∑ m ∣ ∣ x ( i ) − x a p p r o x ( i ) ∣ ∣ 2 。其中 x a p p r o x ( i ) x^{(i)}_{\rm approx} x a p p r o x ( i ) 表示 x ( i ) x^{(i)} x ( i ) 投影到平面上之后的向量。
在定义数据的总体方差为所有特征向量长度平方的平均值:1 m ∑ i = 1 m ∣ ∣ x ( i ) ∣ ∣ 2 \dfrac{1}{m} \sum\limits_{i=1}^m ||x^{(i)}||^2 m 1 i = 1 ∑ m ∣ ∣ x ( i ) ∣ ∣ 2 。
那么主成分的数量 k k k 是满足下面这个不等式最小的 k k k 值:
1 m ∑ i = 1 m ∣ ∣ x ( i ) − x a p p r o x ( i ) ∣ ∣ 2 1 m ∑ i = 1 m ∣ ∣ x ( i ) ∣ ∣ 2 ≤ 0.01 \dfrac{\dfrac{1}{m}\sum\limits_{i=1}^m ||x^{(i)} - x^{(i)}_{\rm approx}||^2}{\dfrac{1}{m} \sum\limits_{i=1}^m ||x^{(i)}||^2} \le 0.01
m 1 i = 1 ∑ m ∣ ∣ x ( i ) ∣ ∣ 2 m 1 i = 1 ∑ m ∣ ∣ x ( i ) − x a p p r o x ( i ) ∣ ∣ 2 ≤ 0 . 0 1
这个不等式意味着:数据中 99 % 99\% 9 9 % 的方差得到了保留。当然,这里的比例可以根据实际情况进行选取,如 95 % 95\% 9 5 % 、90 % 90\% 9 0 % 都是可行的值。
如果枚举 k k k 值进行多次 PCA 以寻找最小的 k k k 值,效率会比较低下。而奇异值分解给予了一个矩阵 S S S ,这个矩阵除了对角线上的元素,其余元素全部为 0 0 0 。而上面的不等式等价于:
∑ i = 1 k S i i ∑ i = 1 n S i i ≥ 0.99 \dfrac{\sum\limits_{i=1}^k S_{ii}}{\sum\limits_{i=1}^n S_{ii}} \ge 0.99
i = 1 ∑ n S i i i = 1 ∑ k S i i ≥ 0 . 9 9
这意味着我们只需要进行一次 PCA ,再利用奇异值分解过程得到的矩阵 S S S 就能够得到最小的 k k k 值。
原始数据的重构
PCA 是一个将高维特征映射到低维空间的算法,当我们得到了高维特征的低维映射,是否存在一个方法,能够还原原来的高维特征呢?
反解方程 z = U r e d u c e T X z = U_{\rm reduce}^TX z = U r e d u c e T X ,就可以得到:x a p p r o x = U r e d u c e z ≈ x x_{\rm approx} = U_{\rm reduce}z \approx x x a p p r o x = U r e d u c e z ≈ x 。这就是 PCA 算法原始数据重构的过程。
使用建议
如果需要在监督学习中使用 PCA ,那么学习 x → z x\to z x → z 的映射的过程只应该应用在训练集上,但是这个映射可以被用于验证集和测试集。
使用 PCA 来防止过拟合通常不是一个好的选择,因为 PCA 会丢失特征里的一些信息,从而降低模型的准确率。并且,PCA 降低过拟合的效果不会比正则化好。
如果不是非要使用 PCA 的情况,尽量不要使用 PCA 。不要在构建机器学习系统最开始的时候,就把 PCA 作为计划的一部分。
第十五章 异常检测
问题描述
给定一个数据集 { x ( 1 ) , x ( 2 ) , ⋯ , x ( m ) } \{x^{(1)}, x^{(2)}, \cdots, x^{(m)}\} { x ( 1 ) , x ( 2 ) , ⋯ , x ( m ) } ,从这些数据集中建立一个模型 p ( x ) p(x) p ( x ) ,通过 p ( x ) p(x) p ( x ) 输出的值来判断新的样本是否正常。
异常检测的常见应用:网站识别异常用户、工厂识别问题产品、计算中心识别有问题的电脑。
高斯分布
高斯分布又被称作为正态分布,其有两个参数,μ \mu μ 控制高斯分布的均值,σ 2 \sigma^2 σ 2 控制高斯分布的方差。变量 x x x 服从高斯分布一般记作 x ∼ N ( μ , σ 2 ) x\sim {\mathcal N}(\mu, \sigma^2) x ∼ N ( μ , σ 2 ) ,其概率密度公式如下:
p ( x ; μ , σ 2 ) = 1 2 π σ exp ( − ( x − μ ) 2 2 σ 2 ) p(x; \mu, \sigma^2) = \dfrac{1}{\sqrt{2\pi}\sigma}\exp{\left(-\dfrac{(x-\mu)^2}{2\sigma^2}\right)}
p ( x ; μ , σ 2 ) = 2 π σ 1 exp ( − 2 σ 2 ( x − μ ) 2 )
对于高斯分布的图像:高斯分布的图像关于 x = μ x=\mu x = μ 对称,且 σ 2 \sigma^2 σ 2 越小,图像越瘦高;σ 2 \sigma^2 σ 2 越大,图像越矮胖。
对于高斯分布的参数估计:一般使用所有样本的平均值估计 μ \mu μ ,使用所有样本的方差估计 σ 2 \sigma^2 σ 2 。即:假设样本数量为 m m m ,那么通过如下公式估计参数:
有的时候取均值不是使用 1 m \dfrac{1}{m} m 1 ,而是使用 1 m − 1 \dfrac{1}{m-1} m − 1 1 。虽然两种写法略有差别,但是总体上差别不大。
异常检测算法
通过高斯分布拟合每一个特征的分布,再利用概率密度计算出新样本的概率分布,判断其与设定的阈值 ϵ \epsilon ϵ 的大小关系。具体步骤如下:
选择 m m m 个能够表示样本是否异常的特征。
估计特征的分布参数:
对于一个新的样本 x x x ,通过如下公式计算 p ( x ) p(x) p ( x ) :
p ( x ) = ∏ i = 1 m p ( x j ; μ j , σ j 2 ) = ∏ i = 1 m 1 2 π σ j exp ( − ( x − μ j ) 2 2 σ j 2 ) p(x) = \prod\limits_{i=1}^m p(x_j; \mu_j, \sigma^2_j) = \prod\limits_{i=1}^m \dfrac{1}{\sqrt{2\pi}\sigma_j}\exp{\left(-\dfrac{(x-\mu_j)^2}{2\sigma^2_j}\right)}
p ( x ) = i = 1 ∏ m p ( x j ; μ j , σ j 2 ) = i = 1 ∏ m 2 π σ j 1 exp ( − 2 σ j 2 ( x − μ j ) 2 )
如果 p ( x ) < σ p(x) < \sigma p ( x ) < σ ,就认为样本有异常。
异常检测算法测试技巧
数据集的构建:使用有标签的数据(正常/异常)构建数据集,但是训练集中的所有样本都应该是正常的 。再将剩下的数据分配给验证集和测试集。不能出现一个样本又在验证集,又在测试集的情况,因为验证集和测试集本质上是两个不同的数据集。
测试指标:可以通过精确率、召回率和 F 1 F_1 F 1 分数对异常检测算法进行测试。
ϵ \epsilon ϵ 的取值可以通过验证集上的测试进行调整。
异常检测与监督学习的对比
异常检测
监督学习
只有少量异常样本,但是有大量的正常样本。
异常样本和正常样本数量都很大,而且数量级相当。
有很多不同种类的异常,很难学习到每种异常的特征。并且未来出现的异常有可能不是已知类型的异常。
有大量的异常样本以让算法能够学习到异常的特征,并且未来出现的异常与已知的异常会非常相似。
特征选择的技巧
选择近似服从于高斯分布的特征,如果特征不服从高斯分布,那么就对其进行变换,以让其服从高斯分布。
通过误差分析来选择特征。对分类错误的样本进行分析,看看能否提取出这些样本中一些共同的特征,以增加模型对这些样本的正确率。
选择一些在异常时会很大,或者很小的特征。这类特征会让异常更容易被检测。
多元高斯分布
假设样本的某些特征存在线性关系,那么通过独立的高斯分布去进行异常检测可能不佳,这个时候就需要使用多元高斯分布将所有特征拟合为一个高斯分布。具体地,假设一共有 n n n 个特征,特征平均值为 μ ∈ R n \mu \in {\mathbb R}^n μ ∈ R n ,特征之间的相关性通过协方差矩阵 Σ ∈ R n × n \Sigma \in {\mathbb R}^{n\times n} Σ ∈ R n × n 来表示,那么这 n n n 个特征的高斯分布概率公式如下:
p ( x ; μ , Σ ) = 1 ( 2 π ) n 2 ∣ Σ ∣ 1 2 exp [ − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ] p(x; \mu, \Sigma) = \dfrac{1}{(2\pi)^{\frac{n}{2}}|\Sigma|^{\frac{1}{2}}}\exp\left[-\dfrac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)\right]
p ( x ; μ , Σ ) = ( 2 π ) 2 n ∣ Σ ∣ 2 1 1 exp [ − 2 1 ( x − μ ) T Σ − 1 ( x − μ ) ]
这里的 ∣ Σ ∣ |\Sigma| ∣ Σ ∣ 表示矩阵 Σ \Sigma Σ 的行列式值。由于协方差矩阵考虑到了变量之间的相关性,所以多元高斯分布在处理具有线性相关性的特征时也会有不错的效果。
多元高斯分布异常检测
多元高斯分布拟合参数的公式如下:
对于一个新的样本 x x x ,计算概率分数的公式如下:
p ( x ) = 1 ( 2 π ) n 2 ∣ Σ ∣ 1 2 exp [ − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ] p(x) = \dfrac{1}{(2\pi)^{\frac{n}{2}}|\Sigma|^{\frac{1}{2}}}\exp\left[-\dfrac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)\right]
p ( x ) = ( 2 π ) 2 n ∣ Σ ∣ 2 1 1 exp [ − 2 1 ( x − μ ) T Σ − 1 ( x − μ ) ]
当 p ( x ) < ϵ p(x) < \epsilon p ( x ) < ϵ 时,就认为新的样本 x x x 时异常的。
高斯分布其实是多元高斯分布在协方差矩阵只有对角元素为非 0 0 0 值(认为不同特征的分布彼此独立)的情况。
下面是多元高斯分布和高斯分布的对比:
多元高斯分布
高斯分布
自动捕捉特征之间的相关性。
手动创建新的特征以捕捉特征之间的特殊组合(如 x 3 = x 1 x 2 x_3 = \dfrac{x_1}{x_2} x 3 = x 2 x 1 )。
计算速度更慢,资源消耗更多。
计算速度更快,资源消耗更少。
必须要满足 m > n m > n m > n 以让矩阵 Σ \Sigma Σ 可逆(一般认为当 m ≥ 10 n m \ge 10n m ≥ 1 0 n 时有充足的样本让高斯分布拟合特征)。
即使当样本量很少时,效果也会不错。
第十六章 推荐系统
问题描述
现有 n u n_u n u 个用户,n m n_m n m 个电影(物品)。我们使用 r ( i , j ) r(i, j) r ( i , j ) 表示用户 i i i 是否为电影 j j j 评分(1 1 1 表示评分,0 0 0 表示未评分),并且使用 y ( i , j ) y^{(i, j)} y ( i , j ) 表示用户 i i i 对电影 j j j 的评分(如果他对电影进行了评分的话)。
推荐系统所做的事情就是:根据这些已有的评分数据,预测用户对他们没有评过分的电影的评分,并且将预测评分高的电影推荐给用户。
基于内容的推荐算法
假设我们已经获得了每个电影的特征向量 x ( i ) x^{(i)} x ( i ) ,那么基于内容的推荐算法会为每个用户学习一个兴趣向量 θ ( j ) \theta^{(j)} θ ( j ) ,并利用 ( θ ( j ) ) T x ( i ) (\theta^{(j)})^Tx^{(i)} ( θ ( j ) ) T x ( i ) 来计算用户 j j j 对电影 i i i 的评分。
对于用户 j j j 的兴趣向量 θ ( j ) \theta^{(j)} θ ( j ) ,其损失函数为:
min θ ( j ) 1 2 ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ k = 1 n ( θ k ( j ) ) 2 \min\limits_{\theta^{(j)}}\dfrac{1}{2}\sum\limits_{i:r(i, j)=1}((\theta^{(j)})^Tx^{(i)} - y^{(i, j)})^2 + \dfrac{\lambda}{2}\sum\limits_{k=1}^n (\theta^{(j)}_k)^2
θ ( j ) min 2 1 i : r ( i , j ) = 1 ∑ ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + 2 λ k = 1 ∑ n ( θ k ( j ) ) 2
对于所有用户的兴趣向量,损失函数为:
min θ ( 1 ) , ⋯ , θ ( n u ) 1 2 ∑ j = 1 n u ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ j = 1 n u ∑ k = 1 n ( θ k ( j ) ) 2 \min\limits_{\theta^{(1)},\cdots,\theta^{(n_u)}}\dfrac{1}{2}\sum\limits_{j=1}^{n_u}\sum\limits_{i:r(i, j)=1}((\theta^{(j)})^Tx^{(i)} - y^{(i, j)})^2 + \dfrac{\lambda}{2}\sum\limits_{j=1}^{n_u}\sum\limits_{k=1}^n (\theta^{(j)}_k)^2
θ ( 1 ) , ⋯ , θ ( n u ) min 2 1 j = 1 ∑ n u i : r ( i , j ) = 1 ∑ ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + 2 λ j = 1 ∑ n u k = 1 ∑ n ( θ k ( j ) ) 2
这里 i : r ( i , j ) = 1 i:r(i,j)=1 i : r ( i , j ) = 1 表示所有满足 r ( i , j ) = 1 r(i, j) = 1 r ( i , j ) = 1 的 i i i 值;n n n 表示特征向量和兴趣向量的维度。
梯度下降公式为:
θ k ( j ) : = { θ k ( j ) − α ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) , k = 0 θ k ( j ) − α ( ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) + λ θ k ( j ) ) , e l s e \theta^{(j)}_k :=
\begin{cases}
\theta^{(j)}_k - \alpha \sum\limits_{i:r(i, j) = 1} ((\theta^{(j)})^Tx^{(i)} - y^{(i, j)})x^{(i)}_k, & k = 0 \\
\theta^{(j)}_k - \alpha\left( \sum\limits_{i:r(i, j) = 1} ((\theta^{(j)})^Tx^{(i)} - y^{(i, j)})x^{(i)}_k + \lambda \theta^{(j)}_k \right), & else
\end{cases}
θ k ( j ) : = ⎩ ⎪ ⎪ ⎪ ⎨ ⎪ ⎪ ⎪ ⎧ θ k ( j ) − α i : r ( i , j ) = 1 ∑ ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) , θ k ( j ) − α ( i : r ( i , j ) = 1 ∑ ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) + λ θ k ( j ) ) , k = 0 e l s e
协同过滤
如果我们并不清楚每个电影的特征向量,那么可以询问每个用户的喜好,先构建出每个用户的兴趣向量,再通过用户的兴趣向量来学习每部电影的特征向量。具体地,给定 θ ( 1 ) , ⋯ , θ ( n u ) \theta^{(1)}, \cdots, \theta^{(n_u)} θ ( 1 ) , ⋯ , θ ( n u ) ,需要学习 x ( 1 ) , ⋯ , x ( n m ) x^{(1)}, \cdots, x^{(n_m)} x ( 1 ) , ⋯ , x ( n m ) ,使得:
min x ( 1 ) , ⋯ , x ( n m ) 1 2 ∑ i = 1 n m ∑ j : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ i = 1 n m ∑ k = 1 n ( x k ( i ) ) 2 \min\limits_{x^{(1)},\cdots,x^{(n_m)}}\dfrac{1}{2}\sum\limits_{i=1}^{n_m}\sum\limits_{j:r(i, j)=1}((\theta^{(j)})^Tx^{(i)} - y^{(i, j)})^2 + \dfrac{\lambda}{2}\sum\limits_{i=1}^{n_m}\sum\limits_{k=1}^n (x^{(i)}_k)^2
x ( 1 ) , ⋯ , x ( n m ) min 2 1 i = 1 ∑ n m j : r ( i , j ) = 1 ∑ ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + 2 λ i = 1 ∑ n m k = 1 ∑ n ( x k ( i ) ) 2
在这个过程中,每个用户都为推荐系统的特征构建做出了贡献,即用户协同起来构建了推荐系统,因此这个过程被称作为协同过滤。
可以发现:我们可以通过迭代运行协同过滤算法和基于内容的推荐算法来迭代学习 θ \theta θ 和 x x x ,从而使它们都收敛到比较合理的值。
将两者结合到一起
在上述过程中,我们需要通过迭代来不断学习 θ \theta θ 和 x x x ,但是也可以同时学习 θ \theta θ 和 x x x ,这个时候,优化目标为:
min θ ( 1 ) , ⋯ , θ ( n u ) , x ( 1 ) , ⋯ , x ( n m ) 1 2 ∑ ( i , j ) : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ j = 1 n u ∑ k = 1 n ( θ k ( j ) ) 2 + λ 2 ∑ i = 1 n m ∑ k = 1 n ( x k ( i ) ) 2 \min\limits_{\theta^{(1)},\cdots,\theta^{(n_u)},x^{(1)},\cdots,x^{(n_m)}}\dfrac{1}{2}\sum\limits_{(i, j):r(i, j)=1} ((\theta^{(j)})^Tx^{(i)} - y^{(i, j)})^2 + \dfrac{\lambda}{2}\sum\limits_{j=1}^{n_u}\sum\limits_{k=1}^n (\theta^{(j)}_k)^2 + \dfrac{\lambda}{2}\sum\limits_{i=1}^{n_m}\sum\limits_{k=1}^n (x^{(i)}_k)^2
θ ( 1 ) , ⋯ , θ ( n u ) , x ( 1 ) , ⋯ , x ( n m ) min 2 1 ( i , j ) : r ( i , j ) = 1 ∑ ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + 2 λ j = 1 ∑ n u k = 1 ∑ n ( θ k ( j ) ) 2 + 2 λ i = 1 ∑ n m k = 1 ∑ n ( x k ( i ) ) 2
在这个学习算法中,将舍弃偏置项,即舍弃 x 0 x_0 x 0 项,只使用 x 1 ∼ x n x_1\sim x_n x 1 ∼ x n 项,因为这个学习算法在自动学习向量之间的关系,如果需要偏置项,那么学习算法会自动学习到这个偏置项。因此梯度下降的过程如下:
向量化:低秩矩阵分解
将用户-电影评分数据处理成一个矩阵 Y ∈ R n m × n u Y\in {\mathbb R}^{n_m\times n_u} Y ∈ R n m × n u ,其中 Y i , j Y_{i, j} Y i , j 表示用户 j j j 对电影 i i i 的评分。那么可以将矩阵 Y Y Y 分解成两个低维矩阵的乘积:X ∈ R n m × n X\in {\mathbb R}^{n_m\times n} X ∈ R n m × n 和 Θ ∈ R n u × n \Theta \in {\mathbb R}^{n_u\times n} Θ ∈ R n u × n ,即通过学习 X X X 和 Θ \Theta Θ ,使得 Θ T X = Y \Theta^T X = Y Θ T X = Y 。这里的 X X X 就是所有电影的特征矩阵,Θ \Theta Θ 就是所有用户的兴趣矩阵。
得到了电影的特征之后,可以通过向量的空间距离来衡量电影之间的相似度。即:如果 ∣ ∣ x ( i ) − x ( j ) ∣ ∣ ||x^{(i)}-x^{(j)}|| ∣ ∣ x ( i ) − x ( j ) ∣ ∣ 越小,就认为电影 i i i 和电影 j j j 越相关。
均值归一化
如果系统中有一个新的用户,通过上述学习方法,这个用户的兴趣向量会是零向量,从而无法给这个用户推荐任何电影。这个时候就需要引入均值归一化,即对每部电影的评分减去该电影评分的平均值 μ i \mu_i μ i ,运用学习算法之后,通过 ( Θ ( j ) ) T x ( i ) + μ i (\Theta^{(j)})^Tx^{(i)} + \mu_i ( Θ ( j ) ) T x ( i ) + μ i 来预测用户 j j j 对电影 i i i 的评分。这样,当用户在系统中没有任何评分数据,系统学习不到用户的喜好时,系统就会把平均分高的电影推荐给用户,相当于为用户推荐被大多数人喜欢的电影。
第十七章 大规模机器学习
大数据集下的学习
在机器学习系统中,使用高方差的模型和海量的数据通常是一个不错的选择。
最终获得胜利的人,不是拥有最好的算法的人,还是拥有最多数据的人。
但是,不能盲目使用大数据集训练机器学习系统,因为大数据集梯度下降的迭代计算效率很低,并且大数据不一定有用(需要先判断过拟合/欠拟合)。
随机梯度下降
相较于 Batch 梯度下降遍历完训练集中的所有数据再进行一次参数更新,随机梯度下降对于每一个样本都进行一次参数更新。具体地,随机梯度下降做法如下:
将所有样本随机打乱。
在每一轮训练中,对于每个样本,都通过如下公式进行所有参数的更新:
θ j : = θ j − α ∂ ∂ θ j J ( θ , ( x ( i ) , y ( i ) ) ) \theta_j := \theta_j - \alpha \dfrac{\partial}{\partial \theta_j}J(\theta, (x^{(i)}, y^{(i)}))
θ j : = θ j − α ∂ θ j ∂ J ( θ , ( x ( i ) , y ( i ) ) )
这里的 J ( θ , ( x ( i ) , y ( i ) ) ) J(\theta, (x^{(i)}, y^{(i)})) J ( θ , ( x ( i ) , y ( i ) ) ) 描述的是对于样本 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) ( x ( i ) , y ( i ) ) ,模型参数为 θ \theta θ 时的损失函数。
虽然在一轮训练中,随机梯度下降算法相较于 Batch 梯度下降法没有时间复杂度上的优势,但是在一轮训练中,随机梯度下降算法已经经过了多次梯度下降,因此随机梯度下降一般不需要太多轮次的迭代,效率会更高。
同时,由于随机梯度下降对于每一个样本都进行一次梯度下降,噪声的存在会让随机梯度下降的梯度下降更加不稳定,曲折下降,但是总体上还是会慢慢收敛到最优解。由于这个不稳定,甚至可以在一定程度上防止陷入局部最优解。
Mini Batch 梯度下降
Mini Batch 梯度下降算法是一个介于 Batch 梯度下降和随机梯度下降之间的梯度下降算法。它以 b b b 个样本为一组,每遍历 b b b 个样本进行一次梯度下降。这个 b b b 就被称作为 mini batch size 。
相较于 Batch 梯度下降,Mini Batch 梯度下降更快,因为不需要遍历整个数据集就能进行梯度下降。因此在一轮训练中就能进行多次梯度下降,从而需要的训练轮次会减少。
相较于随机梯度下降,通过选取合适的向量化计算方式,可以利用线性代数计算库加速梯度的计算,从而效率也会比随机梯度下降更高。
随机梯度下降收敛判断
由于随机梯度下降每遇到一个样本就进行一次损失函数的计算以及参数的更新。那么可以对于每 k k k 次梯度下降(如 k = 1000 k=1000 k = 1 0 0 0 )对损失函数求一次平均值,画出这个平均值随梯度下降次数的变化情况,可以判断随机梯度下降算法是否在收敛。
一般来说,k k k 选取得越大,画出来的图像会越平滑,但是获取结果的延迟也会更大。如果随机梯度下降算法没有在收敛,那么就需要使用更小的学习率。
随机梯度下降一般不会得到全局最优解,而是在全局最优解附近徘徊。
学习率的大小一般保持不变,一个思路是可以动态的改变学习率 α \alpha α 的大小来提高准确度,比如随着迭代次数的增加慢慢减小 α \alpha α 的值。
在线学习
在线学习适用于在线网站,且有庞大的数据流的情况。具体做法为对于数据流中的每一个数据都运用一次随机梯度下降。这样可以让在线的模型学习到用户特征的变化,并且适应用户的新偏好。
Map Reduce 和数据并行
MapReduce 是一种分布式计算框架,旨在处理大规模数据集并实现并行计算。它由两个主要阶段组成:Map(映射)和Reduce(归约)。
在 Map 阶段,输入数据集被划分为一系列的数据块,并由一组并行的 Map 任务处理。每个 Map 任务对输入数据块中的每个元素应用一个映射函数,并产生一系列的键值对作为输出。这些键值对被缓存起来,以供 Reduce 阶段使用。
在 Reduce 阶段,所有的键值对根据键进行排序和分组。然后,一组 Reduce 任务并行处理这些键值对。每个 Reduce 任务接收一个唯一的键以及与该键相关的一组值,并应用一个归约函数来生成最终的结果。
因此,对于大规模机器学习,可以将数据分成多块,每一块分别在不同的机器上计算损失函数,再汇总到中心服务器上计算梯度,分发给集群服务器进行梯度下降。通过这样的方式,就能够提升学习的效率。
第十八章 机器学习案例:OCR
问题描述及 OCR 流水线
OCR 的全称为 Optical Character Recognition,即光学字符识别。OCR 做的事情是:提取图像中的字符,并将这些字符转换为文本数据。
OCR 一般遵循以下步骤:文本检测 → \to → 字符分割 → \to → 字符分类。这里的每一个步骤都可以视为一个机器学习组件。
滑动窗口
对于文本检测任务和字符分割任务,可以通过滑动窗口算法实现。具体地,先训练一个模型,判断一个窗口(矩形框)内是否有我们需要侦测的对象。然后再使用这个窗口(可以放大缩小)遍历整张图片,这样就可以判断出图片中哪些区域存在要侦测的对象。再利用膨胀操作,就可以探测出一个完整的矩形框。
膨胀操作是数字图像处理中的一种形态学操作,常用于图像的分割、边缘检测和形状分析等任务中。它是一种局部操作,通过扩展图像中的目标区域来增强目标的特征。
膨胀操作基于结构元素(也称为膨胀核或模板),它是一个定义了形状和大小的图案。膨胀操作将结构元素与图像进行卷积运算,其中结构元素的每个元素与对应位置的图像像素进行比较。如果结构元素的元素与图像中对应位置的像素相匹配,则将该像素置为目标(前景)像素。
膨胀操作的效果是扩大目标区域并填充目标的孔洞。它可以使目标的边界变得更加粗壮,消除小的空洞,并将目标与其周围的像素连接起来。膨胀操作通常用于去除图像中的噪声、扩展目标的边界以及连接分离的目标部分。
对于文本检测任务,侦测的对象为字符;对于字符分割任务,侦测的对象为字符之间的间隔。
获取大量数据:人工数据合成
人工数据合成有以下几种方式:
将需要检测的目标放置在不同的背景图片上。
对图像进行扭曲等预处理操作。
对语音数据,可以加入不同的背景干扰。
值得注意的是:在使用更多的数据之前,首先确定模型是否为低偏差。只有当模型是低偏差的时候,增加数据才会对模型性能的提升有效。
上限分析
通过逐级将机器学习系统的各个模块设置为 100 % 100\% 1 0 0 % 的准确率,以观察它们对整个系统的准确率的影响,可以分别判断提升这些模块的性能对整体系统性能影响的大小。接下来就可以多花时间在值得提升的模块上。