Andrew Ng机器学习week 2(Linear Regression)编程作业详解

先介绍一下,编程作业分为两部分,必做和选做。

必做部分通过ex1.m来作为主函数执行,选做部分通过ex1_multi.m作为主函数执行。

必做的部分包括提交练习,单参数的梯度优化实践,全部做完 本周就算通过了,系统会给你的程序打分。选做部分是多参数的梯度优化实践,正规方程实践,做完了不会打分,只会显示“Nice work!”

 

1.Simple Octave/MATLAB function

首先是一个简单的示例,这个在视频中有示范过。

在warmUpExercise.m文件中编辑:
A = eye(5);

保存之后,在Octave窗口中输入“ex1”来执行文件。

输出的一个是一个5*5的单位矩阵。(emmmm….不知道为什么我的单位矩阵是歪的)

这步完成之后,可以根据视频里的提交步骤尝试进行第一次作业提交。

2.Linear regression with one variable

下一步,我们尝试用Octave绘图。

根据指导文件的提示,我们在plotData.m文件中写上:

plot(x, y, 'rx', 'MarkerSize', 10);      %Plot the data
ylabel('Profit in $10,000s');            %Set the y-axis label
xlabel('Population of City in 10,000s'); %Set the x-axis label

plot是绘图函数,因为这里是单参数,所以X和y都是m维的向量,“rx”表示用红色叉号符来标记数据,“MakerSize”指定标识符大小,绘制出离散的点。

保存,再回到Octave的命令窗口界面运行“ex1”,可以得到下图:

把数据准备好了,我们要计算代价函数了,这里主要用到了两个公式:

这一步开始,指导文件中不会再给出代码了,你要自己思考怎么通过公式实现功能。

我们先通过computeCost.m来计算损失函数J(θ)

根据文件中给出的两个条件,再结合已知的公式,还是很容易能推算出这一步的程序。在这个文件中,输入以下代码能过关:

J = (sum ((X * theta - y) .^ 2)) / (2*m)

注意运用括号规定运算顺序。

如果代价函数J没算错的话,

当θ取[0;0]的时候,J=32.073

θ取[-1;2]的时候,J=54.242

代价函数算好,终于要来实践梯度下降了。这里我们用到了以下这个公式:

按这个式子的话,用以下这行代码可以通关:

theta = theta - (alpha/m) * (X' * (X * theta - y ));

但是我当初做的时候有点懵逼,主要是没想通最后一个x到底是什么,该怎么乘上去。

我绕了点路,根据网上查到的做法反向推理,再结合自己的笔记,找到了这个式子:

用这个式子的话,就是以下这部分代码:

temp_theta = theta;  % Save the theta from the last iteration
% Update theta0  
theta(1) = temp_theta(1) - (alpha/m) * (sum(X * temp_theta - y));
%Update theta1
theta(2) = temp_theta(2) - (alpha/m) * (sum((X * temp_theta - y) .* X(:,2)));

Octave里头是从1开始计数的,所以是theta(1),theta(2),从我们CS学科的通用理解,其实就是θ(0)和θ(1)。但是要注意一下,这段代码,只能在单因素的时候用,下一部分多因素假设,是不能用这段代码求θ的。

这步完成,我们就能看到拟合出来的结果啦!

执行过程中我们可以观察到J不断下降,直至数值渐渐平稳。

接着我们就可以在屏幕上看到通过我们的程序,得到的预测结果:

可以打开ex1data1.txt文件,扫一眼数值大小,还是可以看出我们的估计算是比较靠谱的。

接下来不用你动手改代码,继续执行ex1,会展示一个网格图,这个图是根据你刚刚编写的computeCost函数,不断迭代J的值得到的效果,绘图函数卸载ex1.m里,可以找到。

在我没搞清楚computeCost函数怎么写的时候,尝试过执行到这一步,图二的红叉叉很明显没到中间的位置,只有现在这么写了,才会回到中间,也就意味着我得到局部最小值了。

不过我的图一颜色没有引导文件里那么丰富多彩,不清楚是为什么,希望有执行出彩虹色的同学可以指正一下我的错误点。

 

以上,必做部分结束。

3.Linear regression with multiple variable

接下来是选做部分,我们要开始尝试多因素的假设。

这里用的示例数据和视频课里比较接近,ex1data2.txt里是房屋的面积、房间数和房屋价格。

首先,根据视频课的内容我们知道,如果要对多因素假设使用梯度下降,必须先对数据进行特征缩放。

“我们通过让每个输入值在大致相同的范围内加速梯度下降。因为θ会在小范围内迅速下降,在大范围内缓慢下降。当变量非常不均匀的时候,θ会低效地下降到最佳值(可能要反复迂回才能达到局部最小)

目的就是使偏移状态减轻。缩小参数落在的区间。

这里我们在featureNormalize.m函数中实现该功能,用到的公式如下:

根据提示,在Octave中可以使用mean函数求得平均值,使用std函数求得标准偏差。填入以下这段代码可以通关:

len = length(X);
mu = mean(X);
sigma = std(X);
X_norm = (X - ones(len, 1) * mu) ./ (ones(len, 1) * sigma);

保存后,执行ex1_multi.m文件,查看效果。

特征缩放之前的数据。

特征缩放之后。

然后我们可以去修改computeCostMulti.m和gradientDescentMulti.m这两个函数了,如果在上一部分你填入的执行模块是通用的话,在这段直接复制进来就好。

引导文件里多提了一句,在多因素假设下,损失函数也可以用下面这个矢量化形式得出:

那么转换成代码,就是这样表示:

J = (((X * theta) - y)') * ((X * theta) - y) / (2*m)

我试了一下,的确算出来一样。

下一步,我们选择最佳的学习率α。

ex1_multi.m中,默认的α大小为0.01(在大概80几行设置),我们可以通过调整这个值观察不同学习率下图像效果。引导文件中给了一个推荐的图像,是迭代50次的效果图。源代码中设置的是迭代400次,我这里也跟着教程修改了一下。

最后,学习率α调到0.13的时候,和引导文件给出的图像比较相近。

 

接下来,我们要自己写预测价格那一块,要求预测1650公顷,3个房间的房子的价格。

仿照上一节中的代码,可以轻松写出代码:

price = [1 1650 3] * theta; % You should change this

但是我发现了一个很大的问题,就是我得出的数据明显比给出的示例图要大个三次的数量级,最后预测出来的结果也异常的大。这是我写这篇详解的动力所在。。。希望实践到这步的你们,能找出我的错误,在评论区或者私信联系我。

视频中还提到另外一种方案,能够一次性求解θ的最优值——正规方程(Normal Equation)。这步直接给出了公式,转换成代码也很简单,在normalEqn.m中增加如下代码即可:
theta = (pinv(X' * X)) * X' * y;

轻松求得预测结果。这里我和数据集比对了一下,还是比较相近的,可信度高。

参考博客:

http://www.cnblogs.com/arcticant/p/3403010.html

http://www.voidcn.com/article/p-cuqfutia-oe.html

4.总结

到这里,Week2的作业就详解完毕了。

完整的代码更新在我的Github上:https://github.com/nutllwhy/Machine-Learning

我是通过Coursera申请奖学金获得的免费学习资源,包括视频课,作业等,完成所有课程之后会颁发一个有一定认证力度的证书。

至于如何使用Coursera,我打算等全部学完之后,再写一篇告知大家。

欢迎讨论。

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据