神经网络:欠拟合和过拟合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了神经网络:欠拟合和过拟合相关的知识,希望对你有一定的参考价值。

参考技术A 以我们前面讲述的线性回归为例,比如我们在训练集上训练出最优的模型,但是当我们将其使用到测试集时,测试的误差很大,我们该怎么办? 

我们一般采取的措施主要包括以下6种:

增加训练样本的数目(该方法适用于过拟合现象时,解决高方差。一般都是有效的,但是代价较大,如果下面的方法有效,可以优先采用下面的方式);

尝试减少特征的数量(该方法适用于过拟合现象时,解决高方差);

尝试获得更多的特征(该方法适用于欠拟合现象时,解决高偏差);

尝试增加多项式特征(该方法适用于欠拟合现象时,解决高偏差);

尝试减小正则化程度λ(该方法适用于欠拟合现象时,解决高偏差);

尝试增加正则化程度λ(该方法适用于过拟合现象时,解决高方差);

上面的方法不是随机选择,是在合适的情况下(过拟合和欠拟合)选择合适的方法,对于怎么判断一个模型是过拟合还是欠拟合,我们会在下面给出一些机器学习诊断法。

如何对一个假设进行评估?  

我们前面在讲述线性回归和逻辑回归时,只是注重针对训练数据集训练出一个最优的参数,但是我们训练处的模型对于测试集的性能好坏我们没有进行判断,我们只是训练的模型使得损失函数最小,我们前面也讨论过,在训练数据集上损失函数最小并不能代表对于给定的测试数据,测试数据的评估非常准确,比如过拟合现象发生时,那我们如何评价一个假设的好坏呢? 

主要的方法包括两种: 

1.对于简答的模型,我们可以采用将hθ(x)的图像画出,来判断模型的好坏,但是这种方法对于特征变量不是一个时,这种方法很难实现或者不可能实现。例如我们曾经看到过这样的图像,可以通过hθ(x)的图像明显可以看出,该假设存在着过拟合现象。 

2.另一种评估假设的方法为:将原来的数据集分为训练集和测试集,一般我们是从原来的数据集中随机选取(保证训练集和测试集中都含有各种类型的数据)70%的数据作为训练集,剩下的30%的样本作为测试集。同时这种将原来数据集划分为训练集和测试集的方法可以用于帮助特征选择、多项式次数的选择以及正则化参数的选择等。数据集划分的过程如下: 

以上面数据集为例,选取前7个为训练集,后3个为测试集。用前7个数据集做训练训练出一个最优的模型,评价这个训练出的模型的好坏可以使用测试集来进行判断,判断的标准可以使用测试集的损失函数来进行定量的衡量。 

对于回归问题,测试集的损失函数计算公式如下: 

Jtest(θ)=12mtest∑i=1mtest(hθ(x(i)test)−y(i)test)2

而对于分类问题,测试集的损失函数计算公式如下: 

这种测量方式,如果测试样本损失函数很大,则代表训练出的模型泛化能力不好。 

对于分类问题,还有另外一种测量的方式,称为误分类率,它对于每一个测试样本进行计算,计算的公式如下: 

error=1mtest∑i=1mtesterr(hθ(x(i)test),y(i)))

其中, 

模型的选择和交叉验证集:  

上述我们是在模型选择好了之后进行训练的,也就是上述我们都是确定了假设进行训练的,但是我们怎么对模型进行选择呢,这一节我们来讨论一下模型的选择,以及和交叉验证集的关系。 

模型选择主要包括以下内容:1.怎样选择正确的特征来构造学习算法?2.怎样选择学习算法中正则化参数λ?等问题。 

首先我们结合一个例子来引出模型的选择和验证集: 

例如我们有上面十个模型,我们对于给定的数据集选择哪种模型呢?按照我们上面讨论的将数据集划分为训练集和测试集,使用训练集对上述模型进行训练,然后使用测试集来进行选择最佳的模型,比如最优的为第五个模型,但是这并不能衡量这个模型的泛化能力,因为测试集已经用于选择最优的模型,这个模型对于其他未知数据的泛化能力还是未知的。 

所以针对上述问题我们可以将数据集划分为训练集、交叉验证集和测试集。一般情况下,训练集占总样本的60%,交叉验证集占20%,测试集占20%。其中训练集用于训练,交叉验证集用于选择最优的模型,测试集用于测试模型的泛化能力。 

模型选择方法为: 

1. 使用训练集训练10个模型; 

2. 用10个模型分别对交叉验证集计算出交叉验证误差(代价函数的值),其中计算公式为: 

3. 选取交叉验证误差最小的模型作为选择的模型; 

4. 用测试集对选择出的模型计算泛化能力(测试样本的损失函数),计算公式如上文中讨论的一样。

假设对诊断偏差和方差(即过拟合还是欠拟合)的影响  

利用上述方法学习到的算法性能不好一般会有两种情况: 

1.会出现过拟合,也就是所谓的方差很大; 

2.会出现欠拟合,也就是所谓的偏差很大; 

首先应该确定算法性能的不好,是由哪种原因造成的,然后针对不同的情况采取不同的改进策略,可以有效的改进当前的算法。下面我们来讲述一下怎么判断是过拟合还是欠拟合。 

以下面例子为例,来进行讨论: 

我们可以通过绘制出训练集的代价函数和交叉验证验证集的代价函数与方次d的关系来进行判断是上述哪种情况的一种: 

对于训练集,当d较小时,模型的拟合程度不是很好,所以训练样本集的代价函数比较大;随着d的增加,模型的拟合程度不断提高,代价函数不断的减小; 

对于交叉验证集,由于d比较小时,模型的拟合程度不是很好,对于新来的样本预测结果会偏差很大,所以交叉验证集的代价函数在初始阶段会很大,而随着d的增加会出现一个比较好的方次d,使得模型的拟合程度最佳,同时对于新来的样本泛化能力很强,所以会有一个代价函数最小的点出现(该转折点即是模型开始由欠拟合转向过拟合的点),随后随着d的增加,由于过拟合,会存在对新的样本预测结果不良的现象,所以代价函数会逐渐增大。 

当我们绘制出上述曲线时,我们就可以判断出什么时候是过拟合什么时候欠拟合,判断的标准如下: 

1. 当训练误差与交叉验证集误差接近时,并且都很大时,该模型高偏差(欠拟合); 

2. 当训练误差远小于验证集误差时,并且训练误差很小时,该模型高方差(过拟合)。 

判断出该模型是过拟合或者欠拟合之后,然后使用上述提到的过拟合和欠拟合的解决方法,对算法进行改进。

正则化对偏差和方差的影响  

我们前面讲述过正则化可以有效的处理过拟合现象,但是我们上述所说的处理过拟合是在合适的λ情况下,那么λ值的大小对模型的性能是怎样影响的呢?我们采用上述与方次d对性能的影响相同的方式来分析λ的值对性能的影响。 

我们首先选择一系列的λ值,通常λ的选择是0~10之间呈现二倍关系的值(如:0,0.01,0.02,0.04,0.08,0.15,0.32,0.64,1.28,5.26,5.12,10) 

构建方式如下: 

选择λ的方法如下: 

1.使用训练集训练处12个不同程度正则化模型; 

2.用12个模型分别对交叉验证集计算出交叉验证误差; 

3.选择得出交叉验证误差最小的模型; 

4.运用步骤3选出的模型对测试集计算得出推广误差

我们同样可以将训练集和交叉验证集模型的代价函数与λ的值绘制在一张图上。对于训练集、验证集和测试集的代价函数计算公式为: 

需要注意的是,当计算训练集、交叉验证集和测试集误差时,不计算正则项,然后绘制出训练集和交叉验证集代价函数与λ值的关系,如下图所示: 

1. 当λ较小时,训练误差较小(过拟合)而交叉验证集误差较大; 

2. 随着λ的增加(从过拟合到欠拟合的过程),训练集误差逐渐增大(欠拟合),而交叉验证集误差则是先减小后增大。

学习曲线  

学习曲线也是一种可以判断算法是否处于过拟合还是欠拟合的情况,学习曲线是将训练集误差和交叉验证集误差作为训练集实例数量(m)的函数绘制的图像。学习曲先不仅可以帮助我们是不是处于过拟合或者欠拟合,它还可以帮助我们判断是否为了提高算法的性能需要我们收集多的数据。 

假设我们有100行数据,我们从第一行数据开始,逐渐增加数据进行训练,得到每次训练数据的代价函数值。当数据很少时,训练模型能够非常完美的拟合很少的数据,但是训练出的模型却不能泛化其他的数据,所以当数据很少时,训练集的代价函数很小,但是交叉验证集的代价函数很大,随着样本的增加,训练集的代价函数逐渐增大,交叉验证集的代价函数逐渐减小。绘制的曲线如下图所示: 

1. 如何用学习曲线识别欠拟合: 

假设我们的模型处于欠拟合的情况下,拟合曲线如下图所示: 

我们可以看出,无论我们怎样增加样本数据,误差都不会有很大改观。同时在欠拟合的情况下,会出现随着样本的增加,训练集代价函数和交叉验证集代价函数都很大的情况,在这种情况下,就没有必要花费时间在收集数据上了,同时这也是一种判断模型是过拟合还是欠拟合的方法。 

2. 如何使用学习曲线识别过拟合: 

假设我们有一个非常高次的多项式模型(比如最高次项达到100次),并且正则化非常小时,从下图可以看出,当交叉验证集误差远大于训练集误差时,往训练集增加更多数据可以提高模型的效果。 

对于过拟合现象时,会出现训练集代价函数一直都很小(虽然是增加的趋势),但是验证集的损失函数会很大(虽然是减小的趋势),同时训练集代价函数和验证集代价函数相差会很大,可以使用这种方法来判断该模型处于过拟合阶段。

对于神经网络我们在讨论一下过拟合和欠拟合现象:  

使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,但是计算代价小;使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算代价比较大,但是可以通过正则化手段来调整而更加适应数据。 

对于 神经网络的模型选择 :我们一般选择较大的神经网络并采用正则化处理,而不会选择较小的神经网络。 

对于 神经网络隐藏层的层数选择 ,一般我们从一层开始逐渐增加层数,为了更好的选择出最佳的层数,可以针对不同隐藏层层数的神经网络进行训练,然后选择交叉验证集代价函数最小的神经网络。

欠拟合和过拟合——机器学习

前言:

作者:神的孩子在跳舞
本人是刚开始学机器学习的小白,以下都是我的学习笔记,有一些是我自己理解的话,所以可能有不对的地方或者有些话只适合我自己理解(仅供参考),不对的希望大家能指出来,另外我创建了一个机器学习交流群903419026,各位跟我一样的小白可以进来多交流交流,互相促进,大佬看见了可以进来指导一下(狗头)。

通俗理解:通过判断一个高级物种是不是人类来进行解决的,通过学习有眼睛,有鼻子有嘴巴就是人类,结果出来一只猫我们也判断是人类,那么这就叫欠拟合,然后我们在训练,接下来在添加皮肤是黄色的就是人类,结果过来一个非洲大哥,判断为不是,这就是过拟合

一. 定义

  1. 过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合, 但是在测试数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)
  2. 欠拟合:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)

二 .过拟合

  1. 效果训练误差小,测试误差大

  2. 原因:原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点

  3. 解决

    (1)重新清洗数据:导致过拟合的一个原因也有可能是数据不纯导致的,如果出现了过拟合就需要我们重新清洗数据。

    (2)增大数据的训练量:还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数据的比例过小。

    (3)正则化(接下来会详细解释)

    (4)减少特征维度,防止维灾难

2.1 正则化——解决过拟合

2.1.1 定义

  1. 响应的进行限制

  2. 有些样本需要训练,训练的过程中,进行拟合,有三种情况发生,直线(欠拟合),曲线,拐来拐去的线(过拟合)

  1. 过拟合变成曲线:尽量减小高次项特征的影响

  2. 类别
    (1)L1正则化(Lasso回归):把高次项系数w的值变为0
    (2)L2正则化(岭回归):把一些系数变得非常小

2.1.2 正则化线性模型

  1. Ridge Regression (岭回归) 使用最多
  1. 岭回归是线性回归的正则化版本,即在原来的线性回归cost function ( 所有样本误差的平均,也就是损失函数的平均 ) 中添加正则项(regularization term)
  2. 放在均方误差里面
  3. 思想:
    (1)就是把系数添加平方项
    (2)然后限制系数值的大小
    (3)α值越小,系数值越大,α越大,系数值越小
  1. Lasso Regression(Lasso 回归)
  1. Lasso Regression 有一个很重要的性质是:倾向于完全消除不重要的权重

  2. 对系数值进行绝对值处理:由于绝对值在顶点处不可导,所以进行计算的过程中产生很多0,最后得到结果为:稀疏矩阵

  1. Elastic Net (弹性网络)

是前两个内容的综合:设置了一个r,如果r=0–岭回归;r=1–Lasso回归

2.2 维灾难

  1. 定义:随着维度的增加,分类器性能逐步上升,到达某点之后,其性能便逐渐下降

  2. 通俗理解:比如要判断一个对应的分类器,分类猫和狗,刚开始我们取一个特征,通过肤色划分,假设所有的花纹状的是猫,黄色的是狗。第二种特征,夏天舌头生出来的是狗,第三个叫声,随着特征增加(维度增多),很明显训练数据就很清楚,但是测试数据由于我们分的太细了就不能判断,容易发生过拟合,同时也是维灾难的体现

三. 波士顿房价预测讲解——岭回归

标准化:是对前面一些方法的封装,在使用线性回归,梯度下降,岭回归,我们会涉及到数据大小的计算,都需要特征工程里面的把数据变成到特定范围内(标准化),在进行值的变换

3.1 API——Ridge

sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,solver="auto", normalize=False)

参数介绍

  1. 具有l2正则化的线性回归
  2. alpha:正则化力度,也叫 λ,通过这个力度来进行响应值的判断,值越大,正则化力度越大,相应的系数会越小,默认值是1
  3. solver:会根据数据自动选择优化方法 sag:如果数据集、特征都比较大,选择该SAG随机梯度下降优化
  4. normalize:默认进行标准化处理 normalize=False:可以在fit之前调用preprocessing.StandardScaler标准化数据
  5. Ridge.coef_:回归权重
  6. Ridge.intercept_:回归偏置

代码

from sklearn.datasets import load_boston#导入数据
from sklearn.model_selection import train_test_split#数据集划分
from sklearn.preprocessing import StandardScaler#特征工程标准化
from sklearn.linear_model import Ridge#岭回归
from sklearn.metrics import mean_squared_error#模型评估

boston=load_boston()
boston

#数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data,boston.target,test_size=0.2)
x_train

transfer=StandardScaler()#实例化一个对象
x_train=transfer.fit_transform(x_train)#通过transform进行转换
x_test=transfer.fit_transform(x_test)
x_train

estimator=Ridge()#实例化一个对象
estimator.fit(x_train,y_train)#训练
print("这个模型的偏置是:\\n",estimator.intercept_)

#预测值和准确率
y_pre=estimator.predict(x_test)
print("预测值:\\n",y_pre)
score=estimator.score(x_test,y_test)
print("准确率:\\n",score)
#均方误差
ret=mean_squared_error(y_test,y_pre)#输出测试的目标值和预测后的预测值
print("均方误差是:\\n",ret)

部分输出

这个模型的偏置是:
 22.766336633663393
预测值:
 [23.72931449 14.23876947 20.82065099 20.37737003 41.32444418 31.51760466
	...
 21.48186817 17.7898301  31.19063626 37.89683539 18.74776502 23.14688806]
准确率:
 0.7461774619211063
均方误差是:
 21.375226392907397

3.2 API——RidgeCV

这个API封装的更牛逼:可以把λ对应的值,可以通过网格搜索进行值的传递

sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)
  1. 具有L2正则化的线性回归,可以进行交叉验证

  2. coef_:回归系数

代码

from sklearn.datasets import load_boston#导入数据
from sklearn.model_selection import train_test_split#数据集划分
from sklearn.preprocessing import StandardScaler#特征工程标准化
from sklearn.linear_model import RidgeCV#岭回归
from sklearn.metrics import mean_squared_error#模型评估

boston=load_boston()
boston

#数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data,boston.target,test_size=0.2)
x_train

transfer=StandardScaler()#实例化一个对象
x_train=transfer.fit_transform(x_train)#通过transform进行转换
x_test=transfer.fit_transform(x_test)
x_train

estimator=RidgeCV(alphas=(0.001,0.1,1,1.0))#实例化一个对象,自动选择一个参数看看那个最好
estimator.fit(x_train,y_train)#训练
print("这个模型的偏置是:\\n",estimator.intercept_)

#预测值和准确率
y_pre=estimator.predict(x_test)
print("预测值:\\n",y_pre)
score=estimator.score(x_test,y_test)
print("准确率:\\n",score)
#均方误差
ret=mean_squared_error(y_test,y_pre)#输出测试的目标值和预测后的预测值
print("均方误差是:\\n",ret)

部分输出

这个模型的偏置是:
 22.54529702970301
预测值:
 [20.80073917 22.01968705 22.07129549 13.1739321  29.19152411 33.26611376
	...
 31.36346221 25.80495191 10.39900086 25.39191069 16.09318826 24.79786881]
准确率:
 0.7216861974681366
均方误差是:
 23.6001418609719

三. 欠拟合

  1. 效果:训练误差和测试误差都很够大

  2. 原因:学习数据特征少

  3. 解决:添加多项式特征,添加其他特征项

本人博客:https://blog.csdn.net/weixin_46654114
本人b站求关注:https://space.bilibili.com/391105864
转载说明:跟我说明,务必注明来源,附带本人博客连接。

请给我点个赞鼓励我吧

以上是关于神经网络:欠拟合和过拟合的主要内容,如果未能解决你的问题,请参考以下文章

欠拟合过拟合及其解决方法

模型选择欠拟合和过拟合(underfit-overfit)

动手深度学习12- 模型选择,欠拟合和过拟合

欠拟合和过拟合的一般解决方法

机器学习欠拟合和过拟合

三欠拟合和过拟合