模型评估、过拟合欠拟合以及超参数调优方法

本文探讨了模型评估的方法,包括泛化能力、留出法、交叉验证、留一法和自助法。此外,文章详细解释了过拟合和欠拟合的概念,并介绍了超参数调优的策略,如手动搜索、网格搜索、随机搜索和贝叶斯优化。重点在于理解如何通过选择合适的模型、调整超参数和处理数据分布不匹配来优化模型性能。

机器学习入门系列(2)–如何构建一个完整的机器学习项目,第十一篇!

该系列的前 10 篇文章:

上一篇文章介绍了性能评估标准,但如何进行模型评估呢,如何对数据集进行划分出训练集、验证集和测试集呢?如何应对可能的过拟合和欠拟合问题,还有超参数的调优,如何更好更快找到最优的参数呢?

本文会一一介绍上述的问题和解决方法。


2. 模型评估的方法

2.1 泛化能力
  1. 泛化能力:指模型对未知的、新鲜的数据的预测能力,通常是根据测试误差来衡量模型的泛化能力,测试误差越小,模型能力越强;
  2. 统计理论表明:如果训练集和测试集中的样本都是独立同分布产生的,则有 模型的训练误差的期望等于模型的测试误差的期望
  3. 机器学习的“没有免费的午餐定理”表明:在所有可能的数据生成分布上,没有一个机器学习算法总是比其他的要好。
    • 该结论仅在考虑所有可能的数据分布时才成立。
    • 现实中特定任务的数据分布往往满足某类假设,从而可以设计在这类分布上效果更好的学习算法。
    • 这意味着机器学习并不需要寻找一个通用的学习算法,而是寻找一个在关心的数据分布上效果最好的算法。
  4. 正则化是对学习算法做的一个修改,这种修改趋向于降低泛化误差(而不是降低训练误差)。
    • 正则化是机器学习领域的中心问题之一。
    • 没有免费的午餐定理说明了没有最优的学习算法,因此也没有最优的正则化形式。
2.2 泛化能力的评估

常用的对模型泛化能力的评估方法有以下几种,主要区别就是如何划分测试集。

  • 留出法(Holdout)
  • k-fold 交叉验证(Cross Validation)
  • 留一法(Leave One Out, LOO)
  • 自助法(bootstrapping)
2.2.1 留出法(Holdout)

留出法是最简单也是最直接的验证方法,它就是将数据集随机划分为两个互斥的集合,即训练集和测试集,比如按照 7:3 的比例划分,70% 的数据作为训练集,30% 的数据作为测试集。也可以划分为三个互斥的集合,此时就增加一个验证集,用于调试参数和选择模型

直接采用 sklearn 库的 train_test_split 函数即可实现,一个简单的示例代码如下,这里简单调用 knn 算法,采用 Iris 数据集。

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier

# 加载 Iris 数据集
dataset = load_iris()
# 划分训练集和测试集
(trainX, testX, trainY, testY) = train_test_split(dataset.data, dataset.target, random_state=3, test_size=0.3)
# 建立模型
knn = KNeighborsClassifier()
# 训练模型
knn.fit(trainX, trainY)
# 将准确率打印
print('hold_out, score:', knn.score(testX, testY))

留出法的使用需要注意:

  1. 数据集的划分要尽可能保持数据分布的一致性,避免因为数据划分过程引入额外的偏差而对最终结果产生影响。比如训练、验证和测试集的类别比例差别很大,则误差估计将由于三个集合数据分布的差异而产生偏差。

    因此,分类任务中必须保持每个集合中的类别比例相似。从采样的角度看数据集的划分过程,这种保留类别比例的采样方式称为“分层采样”。

  2. 即便确定了训练、验证、测试集的比例,还是有多种划分方式,比如排序后划分、随机划分等等,这些不同的划分方式导致单次留出法得到的估计结果往往不够稳定可靠。因此,使用留出法的时候,往往采用若干次随机划分、重复进行实验后,取平均值作为最终评估结果

分层采样的简单代码实现如下所示,主要是调用了 sklearn.model_selection 中的 StratifiedKFold

from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone

def StratifiedKFold_method(n_splits=3):
    '''
    分层采样
    :return:
    '''
    # 加载 Iris 数据集
    dataset = load_iris()
    data = dataset.data
    label = dataset.target
    # 建立模型
    knn = KNeighborsClassifier()
深度学习模型的性能在很大程度上依赖于超参数的选择。超参数是提升模型性能、避免过拟合拟合并加速训练过程的重要环节。以下是一些常见的超参数化技术方法: ### 1. 网格搜索(Grid Search) 网格搜索是一种穷举搜索方法,通过在预定义的超参数空间中进行搜索来找到最组合。该方法将每个超参数划分为若干个候选值,并对所有可能的组合进行评估,最终选择验证集表现最好的一组超参数[^1]。 尽管网格搜索实现简单且易于并行化,但其计算成本较高,尤其是在超参数维度较多时,会出现“维度灾难”问题。 ### 2. 随机搜索(Random Search) 随机搜索网格搜索类似,不同之处在于它不是遍历所有可能的组合,而是从超参数空间中随机采样一定数的组合进行评估。相比网格搜索,随机搜索在高维空间中更高效,因为它能够更快地探索整个搜索空间[^1]。 研究表明,在相同数的迭代下,随机搜索通常比网格搜索更容易找到更超参数组合。 ### 3. 贝叶斯化(Bayesian Optimization) 贝叶斯化是一种基于概率模型的序贯方法,能够智能地选择下一个最有希望的超参数组合进行评估。它通过构建目标函数的概率代理模型(如高斯过程、树结构Parzen估计器等)来预测哪些超参数组合可能带来更好的性能提升[^1]。 贝叶斯化相较于网格搜索和随机搜索更具效率,尤其适用于昂贵的目标函数评估场景。 ### 4. 基于梯度的化(Gradient-Based Optimization) 对于部分连续可微的超参数(如正则化系数、学习率),可以使用梯度下降或自动微分技术进行化。例如,可以将超参数视为可训练变,并通过反向传播更新它们以最小化验证损失[^1]。 这种方法通常要求模型结构支持自动微分,且不适用于离散型超参数。 ### 5. 进化算法(Evolutionary Algorithms) 进化算法是一种启发式方法,模拟自然选择和遗传机制,通过“种群”中的个体不断演化来寻找最解。在超参数化中,每个个体代表一组超参数配置,通过交叉、变异和选择操作不断生成新的候选解[^1]。 这类方法适用于复杂的非凸、非连续搜索空间,适合异步并行执行。 ### 6. 多保真度化(Multi-fidelity Optimization) 多保真度化利用低保真度(如少训练样本、较少训练轮次)评估快速筛选候选超参数,再在高保真度设置下进行精细评估。典型方法包括Hyperband,它结合了随机搜索早停机制,能在有限预算下高效分配资源[^1]。 这种方法特别适用于训练时间较长的深度学习任务。 ### 示例代码:使用 Scikit-Optimize 实现贝叶斯化 ```python from skopt import BayesSearchCV from sklearn.svm import SVC from sklearn.datasets import load_iris # 加载数据 iris = load_iris() X, y = iris.data, iris.target # 定义超参数搜索空间 param_space = { 'C': (0.1, 100, 'log-uniform'), 'gamma': (0.001, 1.0, 'log-uniform') } # 初始化贝叶斯化器 opt = BayesSearchCV( estimator=SVC(), search_spaces=param_space, n_iter=50, cv=5, scoring='accuracy', n_jobs=-1 ) # 执行化 opt.fit(X, y) # 输出最佳参数 print("Best parameters:", opt.best_params_) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

spearhead_cai

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

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

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

打赏作者

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

抵扣说明:

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

余额充值