研究生阶段经常使用到Python和机器学习,作为研0阶段为今后三年打基础,吴恩达老师的机器学习课程乃是必经之路。此课程分为三部分:
- 监督式机器学习:回归与分类(Supervised Machine Learning: Regression and Classification)
- 高级学习算法(Advanced Learning Algorithms)
- 无监督学习,推荐系统,强化学习(Unsupervised Learning, Recommenders, Reinforcement Learning)
在此文中仅介绍第一部分:监督式机器学习:回归与分类(Supervised Machine Learning: Regression and Classification)
引言
什么是机器学习?
第一个机器学习的定义来自于Arthur Samuel。他通过编写跳棋程序,程序通过学习后,玩西洋棋的水平超过了他。于是定义机器学习为:在进行特定编程的情况下,给予计算机学习能力的领域。
另一个年代近一点的定义,由Tom Mitchell提出,他定义的机器学习是,一个好的学习问题定义如下,他说,一个程序被认为能从经验E中学习,解决任务T,达到性能度量值P,当且仅当,有了经验E后,经过P评判,程序在处理T时的性能有所提升。我认为经验E 就是程序上万次的自我练习的经验,而任务T就是下棋,性能度量值P就是它在与一些新的对手比赛时,赢得比赛的概率。
监督学习
① 房价预测(直线/二次函数拟合数据)==> 回归问题(Regression)预测连续的数值输出
② 乳腺癌预测 ==> 分类问题(Classification)预测离散的数值输出 ==> 多个特征的可视化就是多维/轴
其基本思想是,我们数据集中的每个样本都有相应的“正确答案”。再根据这些样本作出预测,就像房子和肿瘤的例子。我们还介绍了回归问题,即通过回归来推出一个连续的输出,之后我们介绍了分类问题,其目标是推出一组离散的结果。
无监督学习
① Google News 新闻专题 ==> 聚类问题(社交网络分析、市场分割)==> 找出大量数据的类型结构
②DNA微阵列 ==> 聚类问题 ==> 个体所含不同类型的DNA序列
③购买课程的顾客 ==> 聚类问题 ==> 目的不同的顾客
无监督学习,它是学习策略,交给算法大量的数据,并让算法为我们从数据中找出某种结构。在无监督学习中,我们已知的数据看上去有点不一样,不同于监督学习的数据的样子,即无监督学习中没有任何的标签或者是有相同的标签或者就是没标签。所以我们已知数据集,却不知如何处理,也未告知每个数据点是什么。别的都不知道,就是一个数据集。你能从数据中找到某种结构吗?针对数据集,无监督学习就能判断出数据有两个不同的聚集簇。这是一个,那是另一个,二者不同。无监督学习算法可能会把这些数据分成两个不同的簇,所以叫做聚类算法,而上述的三个例子都是聚类算法的应用。
线性回归模型(linear regression model)
我们的第一个学习算法是线性回归算法。
让我们通过一个例子来开始:这个例子是预测住房价格的,我们要使用一个数据集,数据集包含某市的住房价格。在这里,我要根据不同房屋尺寸所售出的价格,画出我的数据集。比方说,如果你朋友的房子是1250平方尺大小,你要告诉他们这房子能卖多少钱。那么,你可以做的一件事就是构建一个模型,也许是条直线,从这个数据模型上来看,也许你可以告诉你的朋友,他能以大约220000(美元)左右的价格卖掉这个房子。
它被称作监督学习是因为对于每个数据来说,我们给出了“正确的答案”,即告诉我们:根据我们的数据来说,房子实际的价格是多少。更具体来说,这是一个回归问题。回归一词指的是,我们根据之前的数据预测出一个准确的输出值,对于这个例子就是价格。同时,还有另一种最常见的监督学习方式,叫做分类问题。当我们想要预测离散的输出值,例如,我们正在寻找癌症肿瘤,并想要确定肿瘤是良性的还是恶性的,这就是0/1离散输出的问题。更进一步来说,在监督学习中我们有一个数据集(即上图中右侧表格),这个数据集被称训练集。
此时,我们可以将这个例子抽象为下图的形式:
这就是一个监督学习算法的工作方式,我们把它喂给我们的学习算法,学习算法工作之后,输出一个函数,通常表示为小写 f 表示。f 表示一个函数,输入是房屋尺寸大小,就像你朋友想出售的房屋,因此 f 根据输入的 x 值来得出 y 值,y 值对应房子的价格 因此,f 是一个从 x 到 y 的函数映射。
因而,要解决房价预测问题,我们实际上是要将训练集“喂”给我们的学习算法,进而学习得到一个函数 f ,然后将我们要预测的房屋的尺寸作为输入变量输入给 f ,预测出该房屋的交易价格作为输出变量输出为结果。那么,对于我们的房价预测问题,我们该如何表达 f ?
一种可能的表达方式为:f_{w,b} \left( x \right)=wx + b ,因为只含有一个特征/输入变量,因此这样的问题叫作单变量线性回归问题。
代价函数(cost function)
代价函数是评价模型的一个指标,它可以测量出一组特定参数和训练数据的吻合程度,从而提供了一种选择更好参数的方法。
对于f_{w,b} \left( x \right)=wx + b,w和b是两个可学习的参数,为了衡量w,b对于真实值的匹配程度,采用代价函数来计算模型预测的y与真实值之间的差异。
计算真实值与模型预测值之间的误差。图中J(w,b)就是代价函数的定义,采用均方差计算误差。
J \left( w, b \right) = \frac{1}{2m}\sum\limits_{i=1}^m \left( f_{w,b}(x^{(i)})-y^{(i)} \right)^{2}系数 \(\frac{1}{2m}\) 中的 2 是为了抵消对 J 关于 w,b 求偏导数时式子多出的一个2,使计算更方便。
我们的目标是求得minimize \(J(w, b)\)。线性回归的本质就是找到 w, b 使得代价函数J(w, b)的值最小。
梯度下降(gradient descent)
梯度下降是一个用来求函数最小值的算法,我们将使用梯度下降算法来求出代价函数\(J(w, b)\)的最小值。
梯度下降背后的思想是:开始时我们随机选择一个参数的组合\(\left( {x_{0}},{x_{1}},……,{x_{n}} \right)\),计算代价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合。我们持续这么做直到找到一个局部最小值(local minimum),因为我们并没有尝试完所有的参数组合,所以不能确定我们得到的局部最小值是否便是全局最小值(global minimum),选择不同的初始参数组合,可能会找到不同的局部最小值。
想象一下你正站立在山的这一点上,站立在你想象的公园这座红色山上,在梯度下降算法中,我们要做的就是旋转360度,看看我们的周围,并问自己要在某个方向上,用小碎步尽快下山。这些小碎步需要朝什么方向?如果我们站在山坡上的这一点,你看一下周围,你会发现最佳的下山方向,你再看看周围,然后再一次想想,我应该从什么方向迈着小碎步下山?然后你按照自己的判断又迈出一步,重复上面的步骤,从这个新的点,你环顾四周,并决定从什么方向将会最快下山,然后又迈进了一小步,并依此类推,直到你接近局部最低点的位置。
梯度下降流程:
同时更新 w 和 b,α 是学习率(即下降幅度)乘上 w 和 b 相对于 J(w, b) 的偏导数(即梯度下降的方向,想象二次函数切线)。
学习率α:
学习率越小,梯度下降越慢,需要多次梯度下降才能达到代价函数最小值,学习率越大,梯度下降越快,但容易跳过最小值,出现过拟合现象。可采用逐渐减小的学习率。
此外,批量梯度下降指的是在梯度下降的每一步中,我们都用到了所有的训练样本,在梯度下降中,在计算微分求导项时,我们需要进行求和运算,所以,在每一个单独的梯度下降中,我们最终都要计算这样一个东西,这个项需要对所有 m 个训练样本求和。因此,批量梯度下降法这个名字说明了我们需要考虑所有这一”批”训练样本,而事实上,有时也有其他类型的梯度下降法,不是这种”批量”型的,不考虑整个的训练集,而是每次只关注训练集中的一些小的子集。
多变量回归
目前为止,我们探讨了单变量/特征的回归模型,现在我们对房价模型增加更多的特征,例如房间数楼层等,构成一个含有多个变量的模型,模型中的特征为\(\left( {x{1}},{x{2}},...,{x_{n}} \right)\)。
增添更多特征后,我们引入一系列新的注释:
\(n\) 代表特征的数量
\({x^{\left( i \right)}}\)代表第 \(i\) 个训练实例,是特征矩阵中的第\(i\) 行,是一个向量(vector)。
比方说,上图的
\({x}^{(2)}\text{=}\begin{bmatrix} 1416\\ 3\\ 2\\ 40 \end{bmatrix}\),
\({x}_{j}^{\left( i \right)}\)代表特征矩阵中第 \(i\) 行的第 \(j\) 个特征,也就是第 \(i\) 个训练实例的第 \(j\) 个特征。
将每一项相加,我们的函数会变为f_{w,b} \left( x \right)=w_{1}x_{1} + w_{2}x_{2} +...+ w_{n}x_{n} + b
如果把w和b都看作行向量,这可以看作是f_{w,b} \left( x \right)={w^{T}}x + b,即w的转置点乘(dot product)b
向量化
向量化实际是通过Numpy库将一批数据变为向量,由于向量点乘中每一项都是并行计算,相比与蛮力计算和for循环计算,大大提升了运算效率。
多元线性回归的梯度下降
与单变量线性回归类似,在多变量线性回归中,我们也构建一个代价函数,则这个代价函数是所有建模误差的平方和,即:\(J\left( {x_{0}},{x_{1}}...{x_{n}} \right)=\frac{1}{2m}\sum\limits_{i=1}^{m}{{{\left( f_{w,b} \left({x}^{\left( i \right)} \right)-{y}^{\left( i \right)} \right)}^{2}}}\)
其中:f_{w,b} \left( x \right)=w_{1}x_{1} + w_{2}x_{2} +...+ w_{n}x_{n}
我们的目标和单变量线性回归问题中一样,是要找出使得代价函数最小的一系列参数。 多变量线性回归的批量梯度下降算法为:
求出偏导数后代入:
我们开始随机选择一系列的参数值,计算所有的预测结果后,再给所有的参数一个新的值,如此循环直到收敛,收敛就是指我们找到了参数w和b接近J的最小可能值的情况,也就是得到了\(\min_\limits{\vec w,b}J(\vec w,b)\)
此外,此节还介绍了正规方程,其只是使用高级线性代数库来求解线性回归的参数 w 和 b ,而没有使用迭代梯度下降的一种方法
特征放缩
特征放缩是指通过适当的缩放数据的范围,使得参数取值范围在一个比较合理(容易计算)的区间,有利于后续梯度下降和可视化
具体实现的方法有:特征放缩、均值归一化和Z-score归一化
特征放缩:直接把所有x值除以特征的max值,\(x_{scaled}=\frac{x}{max}\)
均值归一化:求出各个样本的平均数\(\mu_{i}\),通过\(x_{scaled}=\frac{x-\mu }{max - min}\)进行放缩
Z-score归一化:先求出不同样本的均值\(\mu_{i}\),再求出不同样本的标准差\(\sigma_{i}\),通过\(x_{scaled}=\frac{x-\mu }{\sigma}\)进行放缩
学习率选取
首先,我们需要先检查梯度下降是否收敛。
我们可以通过学习曲线(learning curve)来进行判断,如下图所示,学习曲线的纵轴是代价函数\(J(\vec w, b)\),横轴是迭代次数(iterations),注意横轴是迭代次数而非w或b。随着迭代次数的增加,代价函数会趋于收敛,也就是找到了\(\min_\limits{\vec w,b}J(\vec w,b)\)。
如果梯度下降正常运作,那么在每次迭代后代价 J 应该会降低,如果代价 J 反而在某次迭代后增加了,这意味着要么学习率\(\alpha\)选择的不好(通常是过大),要么代码中有bug。所以引出了学习率选取的问题。
选取合适的学习率一般从小到大开始实验。0.001、0.01、0.1、1…,可以使用渐变学习率,通过观察学习曲线判断是否收敛。
特征工程和多项式回归
特征工程:这里主要是说选择合适的特征进行建模,会直接影响模型的拟合,因此要对研究的项目进行一个深入的理解,判断选择哪些特征作为模型的影响因素。
多项式回归:线性回归并不适用于所有数据,有时我们需要曲线来适应我们的数据,比如一个二次方模型或三次方模型。如下图,房屋的价格和尺寸的数据集并不能很好使用直线拟合,可能我们采取二次函数(粉色曲线)拟合得更好,但这没有意义,因为二次函数终究会下降,而我们不希望看到房子尺寸越大反而价格变低。所以我们可以采取三次函数(紫色曲线)来拟合数据集,显然这样的曲线更符合数据分布。
另一种是含有平方根函数的曲线,如下图
注:如果我们采用多项式回归模型,在运行梯度下降算法前,特征缩放非常有必要。
分类
逻辑回归(logistic regression)
分类–逻辑回归模型:当y只有两种结果(通常是0和1)时,称为二元分类问题,使用逻辑回归模型。分类问题的例子有:判断一封电子邮件是否是垃圾邮件;判断一次金融交易是否是欺诈;区别一个肿瘤是恶性的还是良性的。
这里采用的是sigmiod激活函数,通常设置一个阈值0.5,高于阈值被认为是1,低于阈值被认为是0。计算逻辑回归模型的公式:f(x)=g(z)相结合。
决策边界
它对于 y=1 或 y=0 都是中立的,边界两边各是一种情况。当\(x_{i}\)都是一次幂时,决策边界永远是线性的;当高次幂时,就是非线性的了。
逻辑回归的代价函数
对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将\(f_{\vec w,b}(\vec{x})=\frac{1}{1+e^{-(\vec{w} \cdot \vec{x} + b)}}\)带入到这样定义了的代价函数中时,我们得到的代价函数将是一个非凸函数(non-convexfunction),如下图右侧所示。
注:此文中凸函数均以convex function为定义,即向x轴凸。
如上图所示,这意味着我们的代价函数有许多局部最小值,这将影响梯度下降算法寻找全局最小值,因此我们要重新定义逻辑回归的代价函数。
线性回归的代价函数为:J \left( \vec w, b \right) = \frac{1}{m}\sum\limits_{i=1}^m {\frac{1}{2} }\left( f_{\vec w,b}(\vec x^{(i)})-y^{(i)} \right)^{2}。
于是我们重新定义逻辑回归的代价函数为:J \left( \vec{w}, b \right) = \frac{1}{m}\sum\limits_{i=1}^m {L }\left( f_{\vec{w},b}(\vec{x}^{(i)}),y^{(i)} \right),其中\(L\)代表损失函数(Loss)。
损失函数(Loss)衡量的是在一个训练样例上做的如何,通过把所有训练样例上的损失相加得到的是代价函数——衡量在整个数据集上做的如何。损失函数具体如下:
看到给出的方程可能一头雾水,我们是如何得出这个式子呢?我们来看下面的解释来理解。
如上图所示,右侧图给出当 y(i) = 1 时,-log(f(x)) 的函数图像,而我们模型的输出在 0 和 1 之间,所以左侧给出我们需要关注的部分(粉色框出部分)。当 \(f_{\vec w,b}(\vec x^{(i)})\) 接近 1 时,损失函数接近 0,当其接近 0 时,损失函数接近正无穷,因此,当y(i) = 1 时损失函数是合理的。
如上图所示,右侧图给出当 y(i) = 0 时,-log(1-f(x)) 的函数图像,而我们模型的输出在 0 和 1 之间,所以左侧给出我们需要关注的部分。当 \(f_{\vec w,b}(\vec x^{(i)})\) 接近 0 时,损失函数接近 0,当其接近 1 时,损失函数接近正无穷,因此,当y(i) = 0 时损失函数是合理的。
在此基础上,上述损失函数可以简化:
这里使用最大似然估计的统计学原理选择了这个特定的代价函数。可以证明(但超出本课程的范围),此时的代价函数时凸函数。
逻辑回归的梯度下降
即使逻辑回归模型的梯度下降方程看起来和线性回归模型是一样的,但是他们的 f(x) 是不同的,因此是不同的算法。
线性回归的\(f_{\vec w,b}(\vec x)\)等于\(\vec w \cdot \vec x + b\)
逻辑回归的\(f_{\vec w,b}(\vec{x})\)等于\(\frac{1}{1+e^{-(\vec{w} \cdot \vec{x} + b)}}\)(图中括号位置有误,因为z = w·x+b)
过拟合(overfit)
过拟合的定义
左侧图代表模型是欠拟合 (underfit) 的,又称具有高偏差 (high bias),我们认为数据是线性的,但是数据不是线性的,导致数据拟合的很差,所以被称为高偏差。
中间图代表模型是刚刚好的(实际上没有一个专门的名字来描述这种情况)。泛化 (generalization) 意味着模型对于以前从没见过的数据也能做出良好的预测。
右侧图代表模型是过拟合 (overfit) 的,又称具有高方差 (high variance),我们非常努力地拟合每一个训练样例,但是有可能会出现一条曲折的上下起伏的曲线。因此数据集稍有不同,就会导致拟合的曲线不同,所以被称为高方差。
同样的,分类问题也会出现欠拟合和过拟合问题。
解决过拟合
我们可以通过三种方法来解决过拟合问题:
- 收集更多的训练数据
- 尝试选择所有特征的一个子集
- 利用正则化使参数减少
首先我们来介绍第一个方法,收集更多的训练数据
如上图,在少量数据集进行拟合时,有可能拟合出一条上下起伏的曲线,即过拟合。但当收集到更多的训练数据时,也许会使拟合达到刚刚好的状态。但这通常不是一个有效的办法,因为不一定还有更多的数据。
接着我们来介绍第二个方法,尝试选择所有特征的一个子集
尝试选择所有特征的一个子集,意味着选取少量而能反映最佳拟合的特征,但这种方法会导致丢失某些有用的信息。
接着我们来介绍第三个方法,利用正则化使参数减少
正则化的作用是保留所有特征,并尽可能鼓励算法缩小参数的值,从而防止特征产生过大的影响。我们通常只是对 w 使用正则化,而不用去正则化 b,实践中,是否正则化 b 几乎没什么影响。
带有正则化的代价函数
由于我们不知道哪个参数是重要的,所以通常的正则化方式是惩罚所有的特征,更准确的,惩罚所有的\(w_{j}\)。
\(J(\vec w, b)\)的第一项是均方误差,第二项是正则化项。
正则化项中的\(\lambda\)是正则化参数,将后面的正则项也除以 \(2m\),则前后两项都含有 \(\frac{1}{2m}\),可以使选择 \(\lambda\) 值变得更容易一些。尤其是当我们扩充我们的训练集时,由于拥有了更多的训练样本,此时的 \(m\) 值也会变大,那么之前选择的 \(\lambda\) 现在也可能有效。
对于这个新的代价函数,我们有两个目标。第一个是尝试最小化第一项,鼓励算法通过最小化平方误差来很好地拟合训练数据。第二个是尝试最小化第二项,保持所有的 \(w_{j}\) 较小来抑制过拟合,而我们选择的 \(\lambda\) 指定了这两个目标的相对重要性或相对权衡,也就是说我们是如何取舍这两个目标的。
我们来举个例子,仍旧以线性回归预测房价为例:
λ 很小时,导致模型过拟合;λ 很大时,导致模型欠拟合。
线性回归的正则化
线性回归经过正则化后的代价函数为:
相应的,线性回归正则化后的梯度下降公式为:
化简代入后:
与没有使用正则化的梯度下降不同的是,更新 wj 的公式中多了正则化项的偏导数。但要注意的是\(\frac{\lambda }{m}w_{j}\)这一项是不含\(\sum\)求和符的,因为梯度下降是由单个的w一项一项进行的。
正则化工作原理:在每次迭代中,因为\(\alpha\)通常是一个很小的正数,那么\(w_{j}(1-\alpha \frac{\lambda}{m})\)意味着将 \(w_{j}\) 乘以一个略小于 1 的数,使其具有缩小 \(w_{j}\) 的效果。
逻辑回归的正则化
逻辑回归经过正则化后的代价函数为:
注:此处的 \(f_{\vec w, b}(\vec x )\) 定义不再是线性函数,而是应用于 z 的 logistic 函数
相应的,逻辑回归正则化后的梯度下降公式为:
至此,第一部分(监督式机器学习:回归与分类)结束。