照旧,本练习的相关资料链接将会扔到评论区,大家自取
1. 逻辑回归
1.1 绘制数据
本节练习的第一个小内容,就是把数据集的数据点绘制出来,若是对Octave/Matlab熟悉的同学,这一部分应该很简单,不熟悉也没关系,同样的,作业说明书中也给出了相关的代码,在plotData.m
文件中写入便可
pos = find(y == 1);
neg = find(y == 0);
plot(X(pos,1),X(pos,2),'k+','LineWidth',2,'MarkerSize',7);
plot(X(neg,1),X(neg,2),'ko','MarkerFaceColor','y','MarkerSize',7);
最终所绘制的数据图应该是如下的样子
1.2 sigmoid函数
在本节练习的梯度下降算法当中,我们需要用到sigmoid函数,还记得sigmoid函数是什么吗 ↓
该函数常被用作激活函数,而该函数的实现很简单,照抄便是了,打开我们的sigmoid.m
文件,敲下如下代码:
g = 1./(1+e.^(-z));
简简单单,这个函数已经写完啦,接着看下一部分
1.3 代价函数与偏导项
逻辑回归的代价函数,与线性回归是有所区别的,其最大区别之处莫过于代价函数构成的式子不太一样,但是,其所表示的仍是预测值与实际值之间的误差关系,一起来回忆一下课上说讲的代价函数的怎么样子的
此外,在本练习中,我们将使用Octave/Matlab中的优化函数fminunc
来求解代价函数的最优值,当然,若是你有兴趣也可自行使用梯度下降算法进行求解,同样是可以,只是使用高级优化算法的效率会更高
在使用高级优化算法fminunc
函数求解代价函数的最优解时,我们需要计算一个梯度下降算法的中的偏导项,可能你有点迷茫是什么东西,没关系,直接来看看式子
好啦,万事俱备,只欠代码,让我们把如下代码扔到costFunction.m
文件中即可
J = sum(-y.*log(sigmoid(X*theta))-(1-y).*log(1-sigmoid(X*theta)))/m;
grad = sum((sigmoid(X*theta)-y).*X)/m;
倘若你的代码写得正确,理应便会得到跟我一样的结果
1.4 准确度估计
接下来,我们就该运行fminunc
函数来求解最优值,该部分函数作业中已经写好,因此我们只需要继续运行,便可得到最优值
同样的,决策边界函数也不用我们来完成,这时候我们可以看到其决策边界应是如下样子
图像有了,重头戏便是检查一下该决策边界的正确率有多高,在ex2.m
文件代码中可以看到,predict
函数的作用是根据训练好的theta参数和X来预测结果值
就这?代码就相当简单了,把这行代码放到predict.m
文件中
p = sigmoid(X*theta) >= 0.5;
注意,我方框中的那行代码,同样可以作为该题的答案,两种表达二选一均可
可以看到,运行后的预测值与期望值是相同的
2. 正则化的逻辑回归
当训练样本的特征量偏少,而我们又想训练出更好的分类器时,我们就需要用到特征映射 (Feature Mapping) ,把原有的少量特征扩展成多个特征值,该练习中mapFeature.m
文件已经写好特征映射的代码
而特征映射后的特征量众多,又很容易会引发过拟合等问题,这将会导致训练出来的模型泛化性能较差,而为了解决该问题则引入了正则化的思想
2.1 代价函数
正则化的思想,是在代价函数中添加一个优化项,使得所训练出来的模型能够有足够好的泛化性能,下面贴出课堂上讲过的正则化的代价函数
同样的,代价函数改变后,所对应的偏导项也会随之而改变
至于为什么j=0/1时需要分别写开,这里就不再详细叙述了,还没搞清楚的建议重看一遍吴恩达老师对这部分的讲解,而我想告诉你的是,即使的两条式子,但在利用矩阵计算时,仍然可以非常简单地实现
把如下代码扔到costFunctionReg.m
文件中即可
tt = theta;
tt(1,1) = 0;
J = -sum(y.*log(sigmoid(X*theta))+(1-y).*log(1-sigmoid(X*theta)))/m + lambda*sum(tt.^2)/2/m;
grad = sum((sigmoid(X*theta)-y).*X)/m + lambda/m*tt';
毫无疑问最终的运行结果也是我们想要的
2.2 lambda的选择
注意到在代价函数中的正则化项中有一个lambda参数吗,该参数的大小不同也会影响最终的预测结果,我们可以通过修改ex2_reg.m
文件中的代码来看看不同lambda值所得出的不同决策边界
- lambda=0
- lambda=10
- lambda=-1
可以看出,在不同的lambda参数下,所得到最终模型的准确度以及决策边界都是不一样的,有兴趣的同学可以自己多测试几组值的情况