照旧,本练习的相关资料链接将会扔到评论区,大家自取
1. 回顾线性回归的正则化
练习的第一个部分还是线性回归的相关计算公式,可以好好地回顾一下(其实只是为接下来的内容服务而已),所以这个部分就不过多介绍了,还不太熟练的可以看看我前几篇写的练习
1.1 代价函数
把如下代码扔进linearRegCostFunction.m
文件即可,这里再多嘴提醒一句,记得theta的第一个元素是不需要正则化的!!
tt = theta;
tt(1,1) = 0;
J = sum((X*theta-y).^2)/2/m + sum(tt.^2)*lambda/2/m;
然后你应该可以看见如下结果
1.2 梯度
梯度的计算,同样的theta的第一个元素也是不需要正则化的!!接着把下面的代码扔进同一个文件当中即可
grad = sum((X*theta-y).*X)/m + tt'*lambda/m;
同样的,你会得到如下结果,不过这里还要注意一下tt这个向量是一个几乘几的矩阵?一开始我自己做的时候没有进行转置,搞了好久都总是只有一个值对,另外一个值不对,如果有这种情况发生的同学可以好好检查一下整条式子的矩阵规模是否相符合理
2. 偏差与方差
2.1 训练集数量对“代价”的影响
看练习指导书我们可以发现,这里的任务是要绘制一个训练集与验证集的关于数据集(训练集)数量的学习曲线,因此我们需要分别得出训练集与验证集的“代价”,这时候细心的你观察了一下learningCruve.m
中的函数定义发现,这里根本没有定义theta,就是说这个theta值不是从外面传进来的(废话嘛,对于不同数量的数据集得出的theta都不一样)
那么怎么才能得出训练的theta值呢?这时候聪明的我们肯定是先去看一下主函数ex5.m
,然后惊喜地发现这里藏着一个迭代计算theta的函数
好了,万事俱备,我们可以使用for
循环进行书写,把如下代码扔进文件中即可
for i = 1:m
[theta] = trainLinearReg(X(1:i,:), y(1:i,:), lambda);
error_train(i) = sum((X(1:i,:)*theta-y(1:i,:)).^2)/2/i;
error_val(i) = sum((Xval*theta-yval).^2)/2/size(yval,1);
endfor
讲道理你也应该会得出如下曲线图,好好观察一下有没有不一样,有的话一般都是错了(我当初就是)
3. 多项式回归
3.1 多项式特征的生成
第三部分,我们需要生成一个特征多项式,与之前做的练习不同,这里的特征多项式只需要对自己进行指数运算即可
这不是简单了吗?把如下代码扔到polyFeatures.m
中
for i = 1:p
X_poly(:,i) = X.^i;
endfor
讲道理,你也应该能看到如下数值
然后这些图你也是应该可以看到的
练习指导书中还有可选练习,你可以通过更改不同的lambda值观察不同的效果
interesting?yes! 有趣归有趣,最重要的是你需要搞清楚lambda代表的是什么含义,起什么样的调节作用
3.2 lambda对“代价”的影响
最后一个任务是要绘制一个训练集与验证集的关于lambda值大小的学习曲线,嘿?那不是跟前面的一个部分有点像?同样的,我们利用for
循环,把如下代码扔进validationCurve.m
文件
m = size(X,1);
n = size(yval,1);
for i = 1 : length(lambda_vec)
[theta] = trainLinearReg(X, y, lambda_vec(i));
error_train(i) = sum((X*theta-y).^2)/2/m;
error_val(i) = sum((Xval*theta-yval).^2)/2/n;
endfor
得出的图像,也正好直观地表达了lambda值对算法的影响
至此,你应该对关于数据集数量、正则化参数lambda对“代价”的影响有了一个深刻且清晰的了解,看似这章内容并没有让你我学到什么实质性的算法,但这部分内容可以为我们以后优化算法、提高算法准确率提供思路与方向!