交叉验证的原理与用法

作者: 郗南枫 | 来源:发表于2018-06-23 09:40 被阅读11次

    引言

    在机器学习中,交叉验证(cross validation)是一种用来做模型选择的方法。如果给定的样本数据充足,我们可以随机地将数据集切分成训练集、验证集和测试集,训练集用来训练模型,验证集用于模型的选择,而测试集用于最终对方法进行评估。然而实际情况中数据往往是不够充分的,为了更好地选择模型,可以使用交叉验证的方法。

    原理

    具体而言,当我们开始一个机器学习的建模工作时,首先会将数据集切分成训练集和测试集,我们在训练集上进行模型的训练和参数的调优,最终到测试集上验证模型的效果。为了能够选择出最优的模型和参数,我们通常会在训练集中再切分出一小部分作为验证集,通过观察模型在验证集上的效果来评估其好坏。但是如果训练集的数目不太多,那么不同验证集的选择方式可能会对模型的效果有很大影响。因此,我们可以采用交叉验证的方式。最常用的是K-fold交叉验证法,我们随机的将训练集等分为K份,每次训练时取其中的一份作为验证集,剩下的作为训练集,通过观察模型在K次实验中的各个指标的平均值,可以对模型的效果有一个比较准确地了解,而不至于受到验证集选择方式的影响。我们可以设置不同的模型参数并逐一观察它们的平均效果,最终可以选择出一组最优的参数应用到测试集上。

    测试集的选择

    前面我们谈到了使用交叉验证来进行参数选择,其实对于测试集和训练集的切分也可以应用交叉验证的方法。当整个数据集较小时,如何选择合适的测试集也是个问题,在随机切分的情况下,我们可能刚好选择了一些相对容易预测的数据点作为测试集,这会使得我们模型的最终效果看起来很好,但这并不是真实的情况。为了避免这种因为测试集的选择方式所导致的模型效果出现波动的问题,我们也可以使用交叉验证的方式,通过观察模型在多个测试集上的平均效果来总体地评估模型的效果。

    正负样本比

    还有一个值得注意的问题,在二分类问题中,当数据集的正负样本比很低时,对模型的训练是很有挑战的,而实际情况往往就是这样的。这种情况下我们通常希望训练集和测试集中的正负样本比可以和总体的比例保持一致,从而降低不平衡数据集带来的影响,因此我们会采用分层的方式来切分测试集。具体而言,假设我们希望切分25%的数据作为测试集,那么我们的做法是分别随机地选取25%的正例和25%的负例作为测试集,剩下的作为训练集。这种分层抽样的方式在实际情况中是非常必要的。

    幸运的是,在Scikit-Learn中,StratifiedKFold 可以直接帮助我们完成这一点。

    定义

    class sklearn.model_selection.StratifiedKFold(n_splits=3, shuffle=False, random_state=None)
    

    参数

    n_splits : int, default=3
    
    Number of folds. Must be at least 2.
    
    shuffle : boolean, optional
    
    Whether to shuffle each stratification of the data before splitting into batches.
    
    random_state : int, RandomState instance or None, optional, default=None
    
    If int, random_state is the seed used by the random number generator; If RandomState instance, random_state is the random number generator; If None, the random number generator is the RandomState instance used by np.random. Used when shuffle == True.
    

    实例

    >>> from sklearn.model_selection import StratifiedKFold
    >>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
    >>> y = np.array([0, 0, 1, 1])
    >>> skf = StratifiedKFold(n_splits=2)
    >>> skf.get_n_splits(X, y)
    2
    >>> print(skf)  
    StratifiedKFold(n_splits=2, random_state=None, shuffle=False)
    >>> for train_index, test_index in skf.split(X, y):
    ...    print("TRAIN:", train_index, "TEST:", test_index)
    ...    X_train, X_test = X[train_index], X[test_index]
    ...    y_train, y_test = y[train_index], y[test_index]
    TRAIN: [1 3] TEST: [0 2]
    TRAIN: [0 2] TEST: [1 3]
    

    参考

    《统计学习方法》 李航
    sklearn.model_selection.StratifiedKFold


    以上就是本文的全部内容,如果您喜欢这篇文章,欢迎将它分享给朋友们。

    全文系作者原创,仅供学习参考使用,转载授权请私信联系,否则将视为侵权行为。码字不易,感谢支持。

    感谢您的阅读,祝您生活愉快!

    作者:小美哥
    2018-06-23

    相关文章

      网友评论

        本文标题:交叉验证的原理与用法

        本文链接:https://www.haomeiwen.com/subject/vlrryftx.html