coursera—吴恩达Machine Learning笔记(1-3周)
Machine Learning 笔记
笔记主要按照进度记录上课主要内容和部分代码实现,因为我会看一阶段再进行整理,内容会有一定交叉。关于代码部分,一开始我是只为了做作业而写代码的,现在觉得不妨仔细看一遍老师给的代码,把其当作一个技能语言去学习,所以在分享时也会把老师的代码一起放进来。
错误之处欢迎指正,欢迎一起讨论。
l 第一周
首先这门课要求的数学功底比较低,偏向于应用(用吴恩达的话说是如何像木匠大师那样使用工具),属于基础课程,主要讲监督学习和非监督学习,没有涉及算法背后的理论。
监督学习和非监督学习的区别是(我的理解),在你训练的时候有没有告诉数据集对应的真实的y,监督学习是会告诉训练的输入数据应得到的输出是多少的,而非监督学习则是去寻找输入数据背后的结构、规律。典型的监督学习问题如回归和分类。
下面通过比较简单的只有一个变量的线性回归来熟悉一些基本概念,整理如下:
图1-1
介绍完上述概念后,引入损失函数(Cost Function)概念,来显示预测值和实际值之间的偏离。在线性回归中,损失函数表达如下:
图1-2
其中,在只有一个自变量时,。正像上面说的那样,这个损失函数只是在线性回归中的形式,在不同的模型中,损失函数会有不同的形式,而这和接下来要涉及的梯度下降法(Gradient Descent)有关。
特别注意的损失函数和hypothesis的自变量是不一样的,在hypothesis中自变量是x,而损失函数中自变量是。我们只有知道才能求预测值,接着才能算某一个对应的损失函数值,而我们不确定的、最终要求的参数都是。这一层关系一定要明确。
现在来看下我们怎么确定。我们其实最终的愿望是找到使预测值和实际值相差最小的,而这部分体现在损失函数中,我们的目标函数即:
现在我们有两种方法,一个是直接在损失函数两边对求导,直接算出使损失函数取得极值的;另一种方法则是梯度下降法(Gradient Descent),通过迭代来求得合理的。
虽然对梯度下降法背后的原理不理解,但是通过直观的图形还是比较清楚的了解其大概原理(以吴恩达老师上课举的下坡为例)。但是我们需要注意的是,当函数较为复杂时,梯度下降法无法保证找到全局最优解,可能会收敛到局部最优解,即和最初的选择有一定关系。现在我们再来回答上面提到的损失函数有不同形式的问题,因为梯度下降法无法保证找到全局最优解,当损失函数不合适时(局部解很多时),找到的模型的预测效果并不是很好。(这里会涉及到凸优化(convex optimization)的内容)。在线性模型中,我们找到的损失函数是类似碗形状的,是一定会找到全局最优解的。
现在我们来看下在线性回归模型中参数的迭代过程:
图1-3
即(抱歉我没找到求偏导的符号,用delta来代替):
图1-4
其中表示的是赋值符号,在处已补全为1,这样即使对于偏执项上述公式仍可以满足。表示学习率,是一个我们需要选择的参数,如何进行选择会涉及第二周的内容,放到第二周的内容里。
l 第二周
这周仍然讲线性回归,讲了些在实际应用中注意的技巧,也会有相关的编程作业。
先从feature scaling说起,在实际应用中,常常会对不同取值范围的变量x进行回归。但是当取值范围差异很大时,以二元为例,我们得到的等值线(为了方便,我这样称呼它)会是一个长轴和短轴差别很大(很扁)的椭圆。这样的图形会使得我们迭代的次数增多,而当其为圆形时,迭代次数最少(不是很理解其原理)。
根据上述,在进行回归之前,如果我们对变量(这里注意不是变量)进行标准化处理的话,计算的效率会得到提高。常用的标准方法为:
图2-1
因为之前概率和统计的公式背的比较死,自己理解的只有样本标准差,老师上课提及也可以用极差。
下面谈一下学习率选择的问题。可以画出损失函数和迭代次数的图像来观察学习率选择是否合适,如果学习率选择合适的话,损失函数是随着迭代次数逐渐下降的。
如果选择的学习率过小,那么收敛速度会过慢,迭代次数较多;如果学习率选择的过大的话,损失函数可能会不收敛。可以用上面提到的画迭代-损失函数图像来判断学习率是否选择合适了。
下面讲的内容时多项式回归(polynomial regression),(在开始前一直有个问题,和进行回归会不会有多重共线的问题,一年前学的应用统计学都忘记的差不多了,不敢和胡平老师打招呼了。好吧,我就算是学得很好,我也不会和胡平老师打招呼的)。我们之前讨论的都是线性回归,在生活中我们也会遇到非线性的问题,我们可以增加次方项来提高模型的应用性。我们仍用上述的损失函数和迭代关系计算参数。
因为线代知识和Normal equation或者比较简单,或者我解释不清楚(比如pseudo invert),这里就略过了,下面分享下我写代码的思路。
因为word不好敲代码,我直接复制粘贴代码和注释了。
读入数据数据文件,并进行切片,划分出自变量和因变量。m代表样本数。并画出图像。
图2-2
下面对原来的矩阵X添加(按照我个人的理解,我把其成为创建功能)一个全为1的列向量。并创建一个全为0的初始(注意创建中的[和)的区别),然后调用损失函数。
图2-3
在函数中,我用的是循环语句,可能这样写比较麻烦,比较方便的话可以用矩阵运算构成列向量再元素求和进行实现。
图2-4
定义好损失函数,在给定参数的初始值的情况下,进行迭代过程,调用Gradient Descent函数。
图2-5
这是我定义的梯度下降函数,这里我直接进行列向量元素求和来代替循环语句,注意的是参数中更新是同步的。
图2-6
在原来的figure上画图,并加上标题。
图2-7
画出损失函数的图像,linspace应该是类似np中的mgrid的函数,在指定区间内均匀生成指定个数的数。
图2-8
在这里的画损失函数的立体图的代码没特别,好像是要用到surf函数所以需要对原来的损失函数矩阵进行转置。为图像加上标签,并画出等值线。
图2-9
因为后面的多元练习和这个练习相似,所以就不再贴代码了。
l 第三周
这周主要讲了logistic Regression,讨论的是分类问题。
内容通过一个对肿瘤性质(分类变量)的判断的案例来引入,与前面的不同的是,线性回归的因变量是连续变量,而这次的因变量是分类变量。
如果我们用线性模型来进行回归的话,模型会得到无效的点(即y>1),而且模型会对异常点很敏感(这一点不知道怎么理解)。
之后,我们找到了可以把输出压缩在[0,1]之间的sigmoid函数,即
图3-1
其函数图像为:
图3-2
这样我们就得到了logistic的hypothesis:
图3-3
函数的输出值我们可以看成,即给定和数据x后其标签为1的概率。我们如果以0.5作为threshold,即大于等于0.5,我们认为,反之我们认为为0。当时,我们看到,即,这样我们就可以画出决策边界了(decision boundary)。
知道hypothesis之后,接下来定义损失函数。如果仍按照线性回归的方法,也就是均方误差来定义损失函数的话,我们的到的损失函数将会是非凸的,函数形状如下:
图3-4
正因如此,我们需要找到一个新的、凸的损失函数。找到的损失函数如下(个人感觉这个定义应该是交叉熵):
图3-5
知道损失函数之后,就可以知道迭代过程了:
图3-6
图3-7
在Octave中可以使用一些advanced optimization,我们只需写出偏导部分公式即可。
在Octave中的使用方法为:
图3-8
图3-9
这个代码我们在之后的练习中还会碰到。上面我们所述的分类都是二分类,当我们要面对多分类问题时,我们应该怎么做呢?老师给出了一个one-versus-all的方法,即把类别简化为1和0(是或者不是某一分类),算出概率,然后以同样的方法计算出其他类别的概率,取最大的概率类别为其预测的类别。
下面会涉及到一个正则的概念。当我们的feature特别多的时候,我们的模型会特别容易过拟合,也就是在训练集时表现很好但是在测试集上预测结果并不理想。
解决过拟合的方法有两个:一个是删除一些特征,减少特征数量;另一个方法是利用正则方法(我的理解是对参数进行一定的惩罚,即不让参数过大)。我们来看一个正则在线性回归中的例子:
图3-10
注意,是从1开始选取的,也就是不对参数进行惩罚。当我们参数(feature)很多的时候,我们可能不清楚对哪个参数进行正则,比较好的方法是对全部参数都进行正则处理。
上面是线性回归正则化后的损失函数,对于logistic回归而言,其正则化后的损失函数为:
图3-11
那么其迭代公式为:
图3-12
注意,不包括0。下面我分享下我作业中的代码。
首先为补全X,生成初始的,并调用损失函数。
图3-13
在编写损失函数代码前,先编写sigmoid函数。我是用矩阵的元素运算写的函数,输出的矩阵或向量只是每个元素经过了sigmoid函数处理。
图3-14
编写损失函数和定义偏导部分。
图3-15
在定义好损失函数和偏导之后,利用前面说到的advanced optimization进行迭代,计算参数。
图3-16
之后调用函数画出decision boundary,
图3-17
在plotDecisionBoundary函数中,先画出数据的散点图,然后,根据特征判断来做图,当特征小于等于(已加0)3时,直接画出决策边界线。
图3-18
当特征个数大于3时,画出等值线。
图3-19
其中mapFeature是第二个案例增加特征时用到的函数。