通过学习曲线识别过拟合和欠拟合

简介: 本文介绍了如何利用学习曲线识别机器学习模型中的过拟合和欠拟合问题。过拟合发生时,模型过于复杂,对训练数据过拟合,导致测试集表现不佳;欠拟合则是因为模型太简单,无法捕获数据模式,训练和测试集得分均低。学习曲线通过绘制训练和验证损失随训练样本增加的情况来辅助判断。对于过拟合,学习曲线显示训练损失低且随样本增加上升,验证损失降低但不趋近训练损失;欠拟合时,训练和验证损失都高,且两者随着样本增加缓慢改善。通过学习曲线,我们可以调整模型复杂度或采用正则化等方法优化模型泛化能力。

本文将介绍如何通过学习曲线来有效识别机器学习模型中的过拟合和欠拟合。

欠拟合和过拟合

1、过拟合

如果一个模型对数据进行了过度训练,以至于它从中学习了噪声,那么这个模型就被称为过拟合。过拟合模型非常完美地学习了每一个例子,所以它会错误地分类一个看不见的/新的例子。对于一个过拟合的模型,我们会得到一个完美/接近完美的训练集分数和一个糟糕的测试/验证分数。

过拟合的原因:用一个复杂的模型来解决一个简单的问题,从数据中提取噪声。因为小数据集作为训练集可能无法代表所有数据的正确表示。

2、欠拟合

如果一个模型不能正确地学习数据中的模式,我们就说它是欠拟合的。欠拟合模型并不能完全学习数据集中的每一个例子。在这种情况下,我们看到训练集和测试/验证集的分数都很低。

欠拟合的原因:使用一个简单的模型来解决一个复杂的问题,这个模型不能学习数据中的所有模式,或者模型错误的学习了底层数据的模式。

学习曲线

学习曲线通过增量增加新的训练样例来绘制训练样例样本的训练和验证损失。可以帮助我们确定添加额外的训练示例是否会提高验证分数(在未见过的数据上得分)。如果模型是过拟合的,那么添加额外的训练示例可能会提高模型在未见数据上的性能。同理如果一个模型是欠拟合的,那么添加训练样本也没有什么用。' learning_curve '方法可以从Scikit-Learn的' model_selection '模块导入。

 from sklearn.model_selection import learning_curve

我们将使用逻辑回归和Iris数据进行演示。创建一个名为“learn_curve”的函数,它将拟合逻辑回归模型,并返回交叉验证分数、训练分数和学习曲线数据。

 #The function below builds the model and returns cross validation scores, train score and learning curve data
 deflearn_curve(X,y,c):
 ''' param X: Matrix of input features
         param y: Vector of Target/Label
         c: Inverse Regularization variable to control overfitting (high value causes overfitting, low value causes underfitting)
     '''
 '''We aren't splitting the data into train and test because we will use StratifiedKFoldCV.
        KFold CV is a preferred method compared to hold out CV, since the model is tested on all the examples.
        Hold out CV is preferred when the model takes too long to train and we have a huge test set that truly represents the universe
     '''

     le=LabelEncoder() # Label encoding the target
     sc=StandardScaler() # Scaling the input features
     y=le.fit_transform(y)#Label Encoding the target
 log_reg=LogisticRegression(max_iter=200,random_state=11,C=c) # LogisticRegression model
 # Pipeline with scaling and classification as steps, must use a pipelne since we are using KFoldCV
     lr=Pipeline(steps=(['scaler',sc],
                         ['classifier',log_reg]))


     cv=StratifiedKFold(n_splits=5,random_state=11,shuffle=True) # Creating a StratifiedKFold object with 5 folds
 cv_scores=cross_val_score(lr,X,y,scoring="accuracy",cv=cv) # Storing the CV scores (accuracy) of each fold


     lr.fit(X,y) # Fitting the model

     train_score=lr.score(X,y) # Scoring the model on train set

     #Building the learning curve
 train_size,train_scores,test_scores=learning_curve(estimator=lr,X=X,y=y,cv=cv,scoring="accuracy",random_state=11)
 train_scores=1-np.mean(train_scores,axis=1)#converting the accuracy score to misclassification rate
     test_scores=1-np.mean(test_scores,axis=1)#converting the accuracy score to misclassification rate
 lc=pd.DataFrame({"Training_size":train_size,"Training_loss":train_scores,"Validation_loss":test_scores}).melt(id_vars="Training_size")
     return {"cv_scores":cv_scores,
            "train_score":train_score,
            "learning_curve":lc}

上面代码很简单,就是我们日常的训练过程,下面我们开始介绍学习曲线的用处

1、拟合模型的学习曲线

我们将使用' learn_curve '函数通过将反正则化变量/参数' c '设置为1来获得一个良好的拟合模型(即我们不执行任何正则化)。

 lc=learn_curve(X,y,1)
 print(f'Cross Validation Accuracies:\n{"-"*25}\n{list(lc["cv_scores"])}\n\n\
 Mean Cross Validation Accuracy:\n{"-"*25}\n{np.mean(lc["cv_scores"])}\n\n\
 Standard Deviation of Deep HUB Cross Validation Accuracy:\n{"-"*25}\n{np.std(lc["cv_scores"])}\n\n\
 Training Accuracy:\n{"-"*15}\n{lc["train_score"]}\n\n')
 sns.lineplot(data=lc["learning_curve"],x="Training_size",y="value",hue="variable")
 plt.title("Learning Curve of Good Fit Model")
 plt.ylabel("Misclassification Rate/Loss");

上面的结果中,交叉验证准确率与训练准确率接近。

训练的损失(蓝色):一个好的拟合模型的学习曲线会随着训练样例的增加逐渐减小并逐渐趋于平坦,说明增加更多的训练样例并不能提高模型在训练数据上的性能。

验证的损失(黄色):一个好的拟合模型的学习曲线在开始时具有较高的验证损失,随着训练样例的增加逐渐减小并逐渐趋于平坦,说明样本越多,就能够学习到更多的模式,这些模式对于”看不到“的数据会有帮助

最后还可以看到,在增加合理数量的训练样例后,训练损失和验证损失彼此接近。

2、过拟合模型的学习曲线

我们将使用' learn_curve '函数通过将反正则化变量/参数' c '设置为10000来获得过拟合模型(' c '的高值导致过拟合)。

 lc=learn_curve(X,y,10000)
 print(f'Cross Validation Accuracies:\n{"-"*25}\n{list(lc["cv_scores"])}\n\n\
 Mean Cross Validation Deep HUB Accuracy:\n{"-"*25}\n{np.mean(lc["cv_scores"])}\n\n\
 Standard Deviation of Cross Validation Accuracy:\n{"-"*25}\n{np.std(lc["cv_scores"])} (High Variance)\n\n\
 Training Accuracy:\n{"-"*15}\n{lc["train_score"]}\n\n')
 sns.lineplot(data=lc["learning_curve"],x="Training_size",y="value",hue="variable")
 plt.title("Learning Curve of an Overfit Model")
 plt.ylabel("Misclassification Rate/Loss");

与拟合模型相比,交叉验证精度的标准差较高。

过拟合模型的学习曲线一开始的训练损失很低,随着训练样例的增加,学习曲线逐渐增加,但不会变平。过拟合模型的学习曲线在开始时具有较高的验证损失,随着训练样例的增加逐渐减小并且不趋于平坦,说明增加更多的训练样例可以提高模型在未知数据上的性能。同时还可以看到,训练损失和验证损失彼此相差很远,在增加额外的训练数据时,它们可能会彼此接近。

3、欠拟合模型的学习曲线

将反正则化变量/参数' c '设置为1/10000来获得欠拟合模型(' c '的低值导致欠拟合)。

 lc=learn_curve(X,y,1/10000)
 print(f'Cross Validation Accuracies:\n{"-"*25}\n{list(lc["cv_scores"])}\n\n\
 Mean Cross Validation Accuracy:\n{"-"*25}\n{np.mean(lc["cv_scores"])}\n\n\
 Standard Deviation of Cross Validation Accuracy:\n{"-"*25}\n{np.std(lc["cv_scores"])} (Low variance)\n\n\
 Training Deep HUB Accuracy:\n{"-"*15}\n{lc["train_score"]}\n\n')
 sns.lineplot(data=lc["learning_curve"],x="Training_size",y="value",hue="variable")
 plt.title("Learning Curve of an Underfit Model")
 plt.ylabel("Misclassification Rate/Loss");

与过拟合和良好拟合模型相比,交叉验证精度的标准差较低。

欠拟合模型的学习曲线在开始时具有较低的训练损失,随着训练样例的增加逐渐增加,并在最后突然下降到任意最小点(最小并不意味着零损失)。这种最后的突然下跌可能并不总是会发生。这表明增加更多的训练样例并不能提高模型在未知数据上的性能。

总结

在机器学习和统计建模中,过拟合(Overfitting)和欠拟合(Underfitting)是两种常见的问题,它们描述了模型与训练数据的拟合程度如何影响模型在新数据上的表现。

分析生成的学习曲线时,可以关注以下几个方面:

  • 欠拟合:如果学习曲线显示训练集和验证集的性能都比较低,或者两者都随着训练样本数量的增加而缓慢提升,这通常表明模型欠拟合。这种情况下,模型可能太简单,无法捕捉数据中的基本模式。
  • 过拟合:如果训练集的性能随着样本数量的增加而提高,而验证集的性能在一定点后开始下降或停滞不前,这通常表示模型过拟合。在这种情况下,模型可能太复杂,过度适应了训练数据中的噪声而非潜在的数据模式。

根据学习曲线的分析,你可以采取以下策略进行调整:

  • 对于欠拟合:- 增加模型复杂度,例如使用更多的特征、更深的网络或更多的参数。- 改善特征工程,尝试不同的特征组合或转换。- 增加迭代次数或调整学习率。
  • 对于过拟合:- 使用正则化技术(如L1、L2正则化)。- 减少模型的复杂性,比如减少参数数量、层数或特征数量。- 增加更多的训练数据。- 应用数据增强技术。- 使用早停(early stopping)等技术来避免过度训练。

通过这样的分析和调整,学习曲线能够帮助你更有效地优化模型,并提高其在未知数据上的泛化能力。

https://avoid.overfit.cn/post/daca44bbf042471bbd50b1a1514895cf

目录
相关文章
|
2月前
|
机器学习/深度学习 缓存 自然语言处理
【万字长文】大模型训练推理和性能优化算法总结和实践
我们是阿里云公共云 AI 汽车行业大模型技术团队,致力于通过专业的全栈 AI 技术推动 AI 的落地应用。
1695 38
【万字长文】大模型训练推理和性能优化算法总结和实践
|
Windows
已解决Win11报错 OSError: [WinError 1455] 页面文件太小,无法完成操作。
Win11报错 OSError: [WinError 1455] 页面文件太小,无法完成操作。 Error loading "D:\aaaa\envs\gs\lib\site-packages\torch\lib\caffe2_detectron_ops_gpu.dll" or one of its dependencies.
10228 0
已解决Win11报错 OSError: [WinError 1455] 页面文件太小,无法完成操作。
|
机器学习/深度学习 算法
【机器学习】过拟合和欠拟合怎么判断,如何解决?(面试回答)
本文介绍了如何通过观察训练误差和验证误差来判断模型是否出现过拟合或欠拟合,并提供了相应的解决方案,包括增加数据、调整模型复杂度、使用正则化技术等。
1619 1
|
9月前
|
机器学习/深度学习 数据采集 人工智能
量子计算:人工智能训练的未来加速器
量子计算:人工智能训练的未来加速器
532 41
|
机器学习/深度学习 人工智能
【机器学习】有哪些指标,可以检查回归模型是否良好地拟合了数据?
【5月更文挑战第16天】【机器学习】有哪些指标,可以检查回归模型是否良好地拟合了数据?
|
网络协议 安全 中间件
系统架构设计师【第2章】: 计算机系统基础知识 (核心总结)
本文全面介绍了计算机系统及其相关技术,涵盖计算机系统概述、硬件、软件等内容。计算机系统由硬件(如处理器、存储器、输入输出设备)和软件(系统软件、应用软件)组成,旨在高效处理和管理数据。硬件核心为处理器,历经从4位到64位的发展,软件则分为系统软件和应用软件,满足不同需求。此外,深入探讨了计算机网络、嵌入式系统、多媒体技术、系统工程及性能评估等多个领域,强调了各组件和技术在现代信息技术中的重要作用与应用。
1566 4
|
10月前
|
存储 弹性计算 安全
阿里云服务器实例选择:经济型、通用算力型、计算型、通用型、内存型实例选择参考
当我们通过阿里云的活动购买云服务器会发现,相同配置的云服务器往往有多个不同的实例可选,而且价格差别也比较大,例如同样是4核8G的配置的云服务器,经济型e实例活动价格1595.11元/1年起,通用算力型u1实例要955.58元/1年起,而计算型c8i实例则要2845.81元/1年起,价格差别还是比较大的,因此,阿里云经济型、通用算力型、计算型、通用型、内存型实例云服务器有何差别就是很多新手用户比较关心的问题了,下面小编来为大家简单介绍下它们之间的区别。
758 16
|
开发工具 图形学 git
PC 端 LVGL 模拟器之 Visual Studio
PC 端 LVGL 模拟器之 Visual Studio
782 1
|
机器学习/深度学习 算法
全连接层那些事(Fully Connected Layer)
全连接层那些事(Fully Connected Layer)