【Coursera】Machine Learning Regularized Linear Regression and Bias v.s. Variance 第五次编程作业

一、概述

整个五月份都在忙毕设和答辩问题,因此课程听完,作业也是草草做完,没时间写博客。现在答辩完闲下来,要把之前落下的都补上,同时也要再次巩固一下。托毕设的福,matlab用了差不多半年,越发熟练。

本次作业是有关正则化线性回归,以及偏差和方差问题的,偏差与方差问题用于对学习算法进行诊断。

正则化线性回归就是在之前的线性回归基础上加上一个正则化项,用于防止过拟合。

共有4个函数需要完成:linearRegCostFunction,learningCurve,polyFeatures和validationCurve。

二、分析

1、正则化线性回归

线性回归在之前我们已经学过。简而言之,就是利用多项式对目标曲线进行逼近。但是存在如下问题:若只把数据分为训练集和测试集,那么,对训练集符合很好的曲线,可能对测试集的符合并不很好,反而对于训练集符合不那么好的曲线,对测试集的符合相对好一些。这一问题可以称之为过拟合问题。即对于训练集的拟合过度,整个曲线都是训练集的形状了,因此测试集就很容易发现不对。为了解决这一问题,就有了正则化线性回归。

正则化,简而言之,其目的就是为了防止过拟合,手段是控制特定参数的大小,将一些不重要的特性参数变小,将重要的特性参数变大。这里,不重要的特性参数的含义是“不能反映问题本质,仅是训练集数据特有的参数”,重要的特性参数的含义则是“反映问题本质,是所有合理解都具有的参数”。比如说预测一批房子的房价,房间的瓷砖是不是大理石的,这就是不重要的,房间的面积则是重要的。如果训练集数据里边的房子都是大理石的,那么大理石的瓷砖这一参数就会被误认为是重要的,因此测试里面面积很大,但是没有大理石瓷砖的房子可能被认为不值钱,而这是很愚蠢的。正则化就是为了解决这个问题。

虽然正则化听起来很复杂,但是实现很简单。

我们在之前进行线性回归时,步骤是:列出代价函数,列出偏导数,使用梯度下降迭代求解。正则化线性回归也一样。

首先我们来看正则化线性回归的代价函数,如下:

仅比无正则化的线性回归多了后边的一项,看其含义,可知,将所有参数的平方和乘一个lambda再除以2m,然后加入到代价函数中。仅看其效果可以知道,若为了使代价函数最小化,就需要所有参数的平方和较小,同时为了使预测值较为准确,这里就需要得到一个平衡,这也是“将一些不重要的特性变小”的原理,当然,不重要的特性不是钦定的,而是计算机自己得出的。

这里的lambda称作正则化参数。其值越小,则正则化越不明显,过拟合程度越大,想象一下其值为0的最小情况,过拟合程度最大;其值越大,则正则化越明显,想象一下其值逼近正无穷,所有theta值会接近0,这样就变成了一条y=theta0的直线,从而成为欠拟合。

注意,theta参数是从第一个开始的,第零个参数不参与正则化,其原因如下:

要牢记,正则化用于解决过拟合问题,过拟合则是拟合过度,而第零个参数仅仅是一个偏置,对于所有的预测值,它都一视同仁;也就是说,即是出现了过拟合,锅也甩不到人家身上,因此不参与正则化。

计算代价函数的代码如下:

J=(X*theta-y)'*(X*theta-y)/(2*m)+((theta((2:length(theta))))'*(theta((2:length(theta)))))*lambda/(2*m);

然后来计算偏导数。注意偏导数指的是“代价函数对theta的偏导数”,因此,相比于无正则化的线性回归,增加了正则化项后,正则化项也要求偏导数,当然,第零个参数不用求。其代码如下:

grad(1)=(((X(:,1))')*((X*theta)-y))/m;
for j=2:length(grad)
    grad(j)=(((X(:,j))')*((X*theta)-y))/m+theta(j)*lambda/m;
end

最后利用fmincg迭代即可。

注意,在theta维度较少时,不适合使用正则化,因为维度较少,说明其拟合出的曲线较简单,大概就是直线、二次函数等,正则化的话,要不就是无反应,要不就是削成一条直线。题中仅有二维,因此需要lambda为0,即先不进行正则化。

2、偏差与方差

在1中,我们引入了过拟合和lambda。那么,如何判断算法是欠拟合还是过拟合呢?这需要用偏差和方差来判断。

偏差与方差,首先明确一点,必须看公式来理解。

偏差(bias)是指预测值减去真实值,也就是预测的准不准。比如说预测房价是3k,实际是4k,那偏差就是1k。

方差(variance)是指多次相减的差的和,即∑预测值减去预测值的期望,方差就和真实值没有关系。比如说对于不同的房子,房价都是3k,预测值可能是1k,2k,4k等。多个预测值越稳定,那方差就越小。

上述加了删除线是我之前的理解,有误。

泛化误差=偏差+方差+噪声,用来评价一个模型的整体好坏,定义式如下:

E\left ( f,D \right )=\mathbb{E}\left [ (f(x,D)-y_{D})^{2} \right ]

这里的模型,指的是模型空间F,使用训练集D训练出theta,得到的具体模型f。

即在训练集D上,具体模型f的误差是“在训练集D上训练出具体模型f,用测试样本x测试,具体模型f的输出与标记yD的差的平方和”。x不是D中的!!!

把它分解开可得

E(f,D)=\mathbb{E}[(f(x,D)-\overline{f(x)})^{2}]+(\overline{f(x)}-y)^{2}+\mathbb{E}[(y_{D}-y)^{2}]

其中,第一项是方差,第二项是偏差,第三项是噪声。yD指的是测试样本x在数据集中的标记,y指的是真实标记。因此,噪声指的就是数据集的错误率,其值为0即表示数据集是完全符合真实情况的。

在我之前的理解中的偏差,应该是实际上的无噪声的泛化误差,而实际的偏差,指的是“学习算法的期望预测值与真实值之差”。

学习算法的期望预测值指的就是\overline{f(x)},其值等于由D训练出的具体模型f对D中所有样本x的预测值的平均值,因此,对于一个确定的训练集D,其偏差应该是一个数。

实际上的方差,指的是“预测值与学习算法的期望预测值之差的平方的期望”,要想计算它,要算出所有的预测值,分别减去期望,相加再除以训练集中样本总数量,因此,对于D来说,方差也是一个数。在这里再注意一点,方差与真实值没有关系,它只与预测值有关!

举例如下:

对于房价预测问题,选择模型一次函数y=ax+b,参数为a和b,样本值为面积。

那么,模型空间F指的是整个一次函数族,选择三个训练集D1,D2,D3,训练出三个具体模型f1,f2,f3;然后使用测试集d,对于测试集中的样本x,f1,f2,f3的预测值分别为y1,y2,y3。

那么,若x的真实值为5,预测值y1,y2,y3分别为1,6,10,这说明方差和偏差均较大;

预测值分别为3,5,7,说明方差较小,偏差较大;或者是偏差较小,方差较大。对于一维的结果,这两者不好分辨。

预测值分别为5,5,5,说明方差和偏差均较小。

也就是说,使用不同的训练集训练同一模型,得到不同参数,使用同一测试集测试不同参数的同一模型,得到不同结果,观察这个不同结果,得到结论。

然后看这张广为流传的图片,可以更好理解:

这张图片中,红色部分表示的是yD,也就是测试集中的x对应的真实标记,而蓝色小点则代表不同训练集得出的不同具体模型对于x的估计值。其中,左上角的是低偏差加上低方差,即,即使训练集不同,得到的预测值仍然都是正确的;右上角的是低偏差加上高方差,即,若训练集不同,得到的预测值都在正确值附近打转,但是这些预测值之间离得较远;左下角是高偏差加上低方差;即,虽然训练集不同,但是预测值差距都不大,但是预测值都错了;右下角是高偏差加上高方差,一无是处。

再融合模型的复杂度来看,低方差就是将模型简化,比如说y=1,无论输入什么,输出都只有一个,那肯定是抱作一团而不是打转,也就是方差较低,但这样很容易导致高偏差,因为没有任何特异性,而不可能所有的样本都相同;低偏差是指将模型复杂化,比如说用十次函数拟合,这样可以拟合出一个特复杂的曲线,经过所有测试集中的点,这样在训练集的偏差肯定小,但是对于测试集来说,它与训练集相似的概率很小,因此对训练集量身定制的曲线很可能并不合身,从而出现奇奇怪怪的结果,这样方差就很大(当然偏差也不小)。

从上面的分析可以看出,要是计算偏差或者方差,需要使用训练集训练出theta,然后使用测试集中的样本计算

终于把偏差和方差弄清楚了。下一步是看它们与欠拟合和过拟合的关系。

其实已经说明了。欠拟合指的模型太简单,过拟合指的是模型太复杂,因此,欠拟合就应该是高偏差,低方差;过拟合就应该是低偏差,高方差。都不怎么样。

于是要找到一个折中点,让这俩都不大。怎么找呢?使用学习曲线。

学习曲线的纵轴是泛化误差(error),横轴是测试集样本数。其中有两条曲线,一条的样本来自交叉验证集,一条的样本来自训练集。于是引入了交叉验证集的概念。

加入我们有如下的已标记的数据集E,将其分成三份:训练集Et,交叉验证集Ec,测试集Es。

其中,训练集负责迭代求解参数theta,测试集负责检验模型的准确度。

那么问题来了,正则化参数lambda怎么求呢?这时就需要用到交叉验证集了。交叉验证集用于选择那些超参数,也就是通过训练集无法求得的参数,直观来讲就是迭代中值不变的参数,例如本问题中的lambda,还有神经网络中的层数等。在交叉验证集中,theta不变,这些超参数选择不同的值,求出不同的预测值,从而对超参数进行筛选。

于是,学习曲线的含义就清楚了。在测试集样本不断增大的情况下,观察交叉验证集的泛化误差是否减少,若减少,说明将测试集增大是有必要的,否则,没有必要。这也是交叉验证集的另一个用途,画学习曲线。

如何利用学习曲线来判断欠拟合还是过拟合呢?若两条曲线很快趋于平稳,说明增大测试集样本作用较小;并且趋于平稳后的值较为接近,且其值较大,说明误差较大,这种情况下就是高偏差低方差。若交叉验证集曲线不断下降,训练集曲线不断上升,且未趋于平稳,但可以斜率较小,这说明增大测试机样本作用较大;并且它们之间有较大距离,说明误差可以变小,这种情况下是高方差低偏差。

接下来开始代码部分。首先是画学习曲线。learningCurve函数要求分别给出训练集和交叉验证集的误差向量。很简单,就是将训练集不断增大,训练模型,得到一组预测值,然后计算得到一个error;如此多次。

代码如下:

for i=1:m
    Xtrain=X(1:i,:);
    Ytrain=y(1:i);
    ThetaTrain=trainLinearReg(Xtrain, Ytrain, lambda);
    error_t=(Xtrain*ThetaTrain-Ytrain)'*(Xtrain*ThetaTrain-Ytrain)/(2*i);
    error_c=(Xval*ThetaTrain-yval)'*(Xval*ThetaTrain-yval)/(2*length(yval));
    error_train(i) = error_t;
    error_val(i)   = error_c;
end

在得到的误差向量中,对应元素y与下标i的关系是:误差y是当训练集元素个数为i时,训练出的模型fi得到的泛化误差。

这样,y-i曲线即是学习曲线。

上文中仍是以直线拟合作为研究对象的,这太简单,lambda=0,若想lambda发挥作用,需要用高次多项式。高次多项式需要样本值的高次幂值,polyFeatures用于解决这一问题。很蠢。代码如下:

for i=1:p
    X_poly(:,i)=X.^i;
end

接下来需要选择lambda值,利用函数ValidationCurve。该函数将绘制一幅图像,与学习曲线类似,也有两条曲线,也是来自训练集和交叉验证集,纵轴也是泛化误差,但是横轴不同,该曲线横轴为lambda的值。即,选择不同的lambda,使用同一训练集训练模型,得到不同模型,返回误差向量。代码也与学习曲线类似,如下:

 for i = 1:length(lambda_vec)
     lambda = lambda_vec(i);
     theta=trainLinearReg(X, y, lambda);
     error_t=(X*theta-y)'*(X*theta-y)/(2*length(y));
     error_c=(Xval*theta-yval)'*(Xval*theta-yval)/(2*length(yval));
     error_train(i)=error_t;
     error_val(i)=error_c;
 end

从而可以画出曲线。

于是可以选择出最佳的lambda值。最佳值应是交叉验证集的泛化误差最小的值。

对于lambda值与学习曲线的关系,学习曲线确定某模型好还是不好,是针对某个模型空间确定的;而引入lambda值之后,模型空间就有了变化,因此lambda可以平衡方差和偏差;学习曲线也可以评价模型好坏。

三、总结

本次作业并不难,但是其背后的原理较难理解。需要仔细琢磨。本人的理解也不一定正确,有错误之处敬请指正。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值