使用学习曲线(Learning curve),判断机器学习模型过拟合、欠拟合,与解决过拟合、欠拟合的问题

本文介绍了过拟合和欠拟合的概念,通过学习曲线进行识别,并提供了绘制学习曲线的代码示例。解决过拟合的方法包括正则化、早停等,而欠拟合可通过增加模型复杂度或数据量来改善。关键在于平衡模型的偏差与方差,以达到理想的预测效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.基本概念

过拟合与欠拟合

  • 过拟合(学成书呆子了):指模型在训练集上表现优秀,在测试集上表现很差
  • 欠拟合(还没学明白):指模型难以学习已有的规律,在训练集和测试集上表现得都很差;或是模型过早的停止训练

根据学习曲线判断过拟合、欠拟合

在实际的使用过程中,过拟合、欠拟合是一个较为主观的评价,没有一个指标能拍板说它就是过拟合了、或就是欠拟合了。而且,过拟合与欠拟合实际上并不是相对的概念,即并未非此即彼,往往:

  • 模型效果太差:欠拟合
  • 模型在训练集上还可以,但测试集上太差:过拟合
  • 模型训练集和测试集都还行:不存在过拟合与欠拟合

下面是一个例子:
在这里插入图片描述
上图是一个比较经典的示意图:

  • 左上角:我们看到随着训练数据的增加(随着x不断增加),准确率趋于稳定,意味着:再添加更多数据,已经无法使模型更好了,说明模型已经到极限了,这就是正常的。但是此时模型的准确率也太低了,如果我们的预期是红色的线,说明模型已经尽力了,也无法达到我们的预测,此时它就是欠拟合的。
  • 右上角:我们看到训练的曲线与验证的曲线相差加大(两条线离的有点远),即:在训练集上效果还行(绿色虚线比较高),但验证集上效果不行(蓝色实线),此时为过拟合
  • 右下角:完美,既不存在过拟合也不存在欠拟合

2.示例代码:绘制学习曲线

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.model_selection import learning_curve
import seaborn as sns
from sklearn.datasets import make_classification


def main():
    data_x, data_y = make_classification(n_samples=1000, n_classes=4, n_features=10, n_informative=8)  # 生成分类任务
    # 绘制学习曲线
    model = SVC(kernel="linear")
    train_sizes, train_scores, valid_scores = learning_curve(
        model, data_x, data_y, train_sizes=np.linspace(0.1, 1.0, 10), cv=5, random_state=0)
    train_scores_mean = np.mean(train_scores, axis=1)  # 纵向求平均
    valid_scores_mean = np.mean(valid_scores, axis=1)
    # 开始绘图
    sns.set()
    sns.lineplot(x=train_sizes, y=train_scores_mean, label="train")
    sns.lineplot(x=train_sizes, y=valid_scores_mean, label="valid")
    plt.xlabel("data")
    plt.ylabel("acc")
    plt.title("SVM linear")
    plt.show()


if __name__ == '__main__':
    main()

得到结果:
在这里插入图片描述

3.解决过拟合、欠拟合

我们可以参考这个图
在这里插入图片描述

解决过拟合

核心:降低模型复杂度,或增加数据的复杂程度

  1. 降低模型复杂度
  2. L1\L2\Dropout 正则化(这里Dropout是深度学习中的方法:随机将一些连接置零)
  3. Early stopping (提前终止)
  4. 通过数据增强处理数据

解决欠拟合

欠拟合基本上都会发生在训练刚开始的时候,因此解决欠拟合的核心是:增加模型复杂度,或降低数据的学习难度

  1. 增加模型复杂度
  2. 增加数据量
  3. 增加特征

4. 过拟合、欠拟合的深层理解

评价模型的指标,就是在已有的数据上平衡两种东西:表现出偏差方差

  • 简单的模型拥有测试集上更大的偏差,但由于整体不复杂,因此偏差的方差较小,某种程度上称欠拟合;
  • 复杂的模型拥有测试集上更小的偏差,但由于较为复杂,因此偏差的方差较大,称过拟合;

如果是较大的偏差较大的方差,则说明模型废了;较小的偏差与较小的方差是我们努力的方向!
在这里插入图片描述

### 如何检测和区分机器学习中的过拟合拟合机器学习领域,过拟合拟合是常见的两类问题。为了有效识别这些问题,可以采用多种方法来评估模型性能。 #### 学习曲线分析 一种常用的方法是通过绘制 **学习曲线** 来观察模型的表现。学习曲线展示了随着训练数据量的变化,模型在训练集和验证集上的误差变化趋势[^1]。 - 如果模型在训练集上表现良好但在验证集上表现较差,则可能表明存在过拟合现象。 - 若模型在训练集和验证集上的误差均较高,则可能是拟合的结果。 #### 偏差方差分解 另一种视角是从偏差和方差的角度出发。当模型表现出较大的偏差时,通常意味着它未能充分捕捉数据中的模式,这通常是拟合的标志;而较高的方差则表示模型对噪声过于敏感,这是典型的过拟合特征[^2]。 #### 数据分布比较 还可以通过对训练数据和测试数据之间的分布差异进行对比来辅助判断。如果模型仅能很好地适应训练数据而在新数据上泛化能力不足,则说明可能存在过拟合问题[^3]。 以下是基于上述理论的一个简单代码实现用于生成并可视化学习曲线: ```python import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import learning_curve from sklearn.linear_model import LogisticRegression def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None, n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5)): plt.figure() plt.title(title) if ylim is not None: plt.ylim(*ylim) plt.xlabel("Training examples") plt.ylabel("Score") train_sizes, train_scores, test_scores = learning_curve( estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes) train_scores_mean = np.mean(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) plt.grid() plt.plot(train_sizes, train_scores_mean, 'o-', color="r", label="Training score") plt.plot(train_sizes, test_scores_mean, 'o-', color="g", label="Cross-validation score") plt.legend(loc="best") return plt # Example usage with logistic regression model X, y = ... # Your dataset here plot_learning_curve(LogisticRegression(), "Learning Curve", X, y, cv=5).show() ``` 此脚本可以帮助直观地看到不同大小样本下模型的学习效果,从而帮助诊断是否存在过拟合拟合状况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆萌的代Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值