先介绍一下,编程作业分为两部分,必做和选做。 必做部分通过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”,可以得到下图:
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)。但是要注意一下,这段代码,只能在单因素的时候用,下一部分多因素假设,是不能用这段代码求θ的。 这步完成,我们就能看到拟合出来的结果啦!
在我没搞清楚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,我打算等全部学完之后,再写一篇告知大家。 当然,迫不及待的,可以加群问我: