• 机器学习之交叉验证汇总及其Python代码


    交叉验证是什么?
    在模型建立中,通常有两个数据集:训练集(train)和测试集(test)。训练集用来训练模型;测试集是完全不参与训练的数据,仅仅用来观测测试效果的数据。

    一般情况下,训练的结果对于训练集的拟合程度通常还是挺好的,但是在测试集总的表现却可能不行。比如下面的例子:


     图一的模型是一条线型方程。 可以看到,所有的红点都不在蓝线上,所以导致了错误率很高,这是典型的不拟合的情况
    图二 的蓝线则更加贴近实际的红点,虽然没有完全重合,但是可以看出模型表示的关系是正确的。
    图三,所有点都在蓝线上,这时候模型计算出的错误率很低,(甚至将噪音都考虑进去了)。这个模型只在训练集中表现很好,在测试集中的表现就不行。 这是典型的‘过拟合’情况。

    总结思想:进行交叉验证目的是为了充分利用训练数据,最大程度利用训练数据,以获得一个较好的模型,防止模型欠拟合或者过拟合。 

    交叉验证:就是在训练集中选一部分样本用于测试模型。
    保留一部分的训练集数据作为验证集/评估集,对训练集生成的参数进行测试,相对客观的判断这些参数对训练集之外的数据的符合程度。
     

    留一验证(LOOCV,Leave one out cross validation )
    只从可用的数据集中保留一个数据点,并根据其余数据训练模型。此过程对每个数据点进行迭代,比如有n个数据点,就要重复交叉验证n次。例如下图,一共10个数据,就交叉验证十次。

     优点:
    适合小样本数据集
    利用所有的数据点,因此偏差将很低
    缺点:
    重复交叉验证过程n次导致更高的执行时间
    测试模型有效性的变化大。因为针对一个数据点进行测试,模型的估计值受到数据点的很大影响。如果数据点被证明是一个离群值,它可能导致更大的变化
     

    总结:实际中基本不用 

    LOOCC是保留一个数据点,同样的你也可以保留P个数据点作为验证集,这种方法叫LPOCV(Leave P Out Cross Validation)
    下面给出LPOCV代码:

    1. from sklearn.model_selection import LeavePOut
    2. lpo = LeavePOut(p=200)
    3. for k, (train_index, test_index) in enumerate(lpo.split(train)):
    4. train_data, test_data, train_target, test_target = train.iloc[
    5. train_index], train.iloc[test_index], target[train_index], target[
    6. test_index]

    普通交叉验证:
    交叉验证的步骤如下:

    保留一个样本数据集, (取出训练集中20%的样本不用)
    使用数据集的剩余部分训练模型 (使用另外的80%样本训练模型)
    使用验证集的保留样本。(完成模型后,在20%的样本中测试)
    如果模型在验证数据上提供了一个肯定的结果,那么继续使用当前的模型。
     

    优点: 简单方便。直接将训练集按比例拆分成训练集和验证集,比如50:50。


    缺点: 没有充分利用数据, 结果具有偶然性。如果按50:50分,会损失掉另外50%的数据信息,因为我们没有利用着50%的数据来训练模型。

    Python 使用train_test_split  案例:

    1. # 切分数据 训练数据80% 验证数据20%
    2. train_all, test_all, train_target, test_target = train_test_split(
    3. traindf, target, test_size=0.2, random_state=0)

    K折交叉验证(k-fold cross validation)

    针对上面通过train_test_split划分,从而进行模型评估方式存在的弊端,提出Cross Validation 交叉验证。
    Cross Validation:简言之,就是进行多次train_test_split划分;每次划分时,在不同的数据集上进行训练、测试评估,从而得出一个评价结果;如果是5折交叉验证,意思就是在原始数据集上,进行5次划分,每次划分进行一次训练、评估(每次都是一个普通的交叉验证),最后得到5次划分后的评估结果,一般在这几次评估结果上取平均得到最后的 评分。k-fold cross-validation ,其中,k一般取5或10。

     

     优点:
    适合大样本的数据集
    经过多次划分,大大降低了结果的偶然性,从而提高了模型的准确性。
    对数据的使用效率更高。train_test_split,默认训练集、测试集比例为3:1。如果是5折交叉验证,训练集比测试集为4:1;10折交叉验证训练集比测试集为9:1。数据量越大,模型准确率越高。
    缺点:未考虑类别的影响
    对数据随机均等划分,不适合包含不同类别的数据集。比如:数据集有5类数据(ABCDE各占20%),抽取出来的也正好是按照类别划分的5类,第一折全是A,第二折全是B……这样就会导致,模型学习到测试集中数据的特点,用BCDE训练的模型去测试A类数据、ACDE的模型测试B类数据,这样准确率就会很低。

     Python 使用cross_val_score或者KFold:(下面用KFold)

    1. from sklearn.datasets import load_digits
    2. from sklearn.model_selection import KFold
    3. import pandas as pd
    4. # 加载测试专用数据集
    5. train, target = load_digits(return_X_y=True)
    6. train = pd.DataFrame(train)
    7. target = pd.DataFrame(target)
    8. # K折交叉验证 K-fold CV
    9. # 5折交叉验证
    10. kf = KFold(n_splits=5)
    11. for k, (train_index, test_index) in enumerate(kf.split(train)):
    12. train_data, test_data, train_target, test_target = train.iloc[
    13. train_index], train.iloc[test_index], target.iloc[train_index], \
    14. target.iloc[
    15. test_index]

     分层交叉验证 (Stratified k-fold cross validation)

    分层是重新将数据排列组合,使得每一折都能比较好地代表整体。
    比如下面这个例子:在一个二分类问题上,原始数据一共有两类(F和M),F:M的数据量比例大概是 1:3;划分了5折,每一折中F和M的比例都保持和原数据一致(1:3)。

    这样就避免了随机划分可能产生的的情况,像是一折全是F,其他3折都是M。
     

    下图是标准交叉验证和分层交叉验证的区别:
    标准交叉验证(即K折交叉验证):直接将数据分成几折;
    分层交叉验证:先将数据分类(class1,2,3),然后在每个类别中划分三折。
     

     

     总结:

    StratifiedKFold用法类似Kfold,但是它是分层采样,确保训练集,验证集中各类别样本的比例与原始数据集中相同。因此一般使用StratifiedKFold。
     

    1. from sklearn.model_selection import StratifiedKFold
    2. kf = StratifiedKFold(n_splits=5)
    3. for k, (train_index, test_index) in enumerate(kf.split(train, target)):
    4. train_data, test_data, train_target, test_target = train.iloc[
    5. train_index], train.iloc[test_index], target[train_index], target[
    6. test_index]

  • 相关阅读:
    Linux17 jdk tomcat idea mysql在linux上安装
    python将.mat文件转换为.txt
    人工智能知识全面讲解:Boosting族算法
    SLM6500原厂2A同步降压型锂电池充电电路
    Linux运维:网络管理
    Alibaba 架构师纯手工打造神仙级“2022 版 Java 面试手册”
    maven多仓库私库模板配置
    JS起源与简介
    【精通内核】计算机程序的本质、内存组成与ELF格式深度解析
    Ribbon本地实现负载均衡
  • 原文地址:https://blog.csdn.net/qq_44386182/article/details/127103787