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

机器学习入门系列(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()
    print('use StratifiedKFold')
    skfolds = StratifiedKFold
  • 7
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

spearhead_cai

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

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

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

打赏作者

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

抵扣说明:

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

余额充值