sklearn之交叉验证

匿名 (未验证) 提交于 2019-12-03 00:17:01

一、简介

  在用机器学习训练模型的时候,会将数据集D划分成训练集和测试集,因为如果在相同的数据上训练并测试无法评估模型的效果,常用的划分方法有K折交叉验证、p次k折交叉验证、留出法、留一法、留P法、随机分配、自助法等。另外,在训练模型的时候,经常需要进行调参,当我们有一堆参数的时候,也可以用类似的较差验证的方式依次使用不同的参数建模,最后选择最好的一个参数。在sklearn中要实现主要用sklearn.model_selection包的各种类,下面进行详细介绍。

二、数据集交叉验证方法

1、留出法

  留出法的方法很简单,将数据集D分为两个部分,一个作为训练集另一个作为测试集,一般会选择70%的数据作为训练集。

对应的方法:

  sklearn.model_selection.train_test_split(*arrays, **options)

  • *arrays:数组,可以传入多个,例如同时传入x,y或者传入x,y,z。传入的数据类型为lists,、numpy arrays、scipy-sparse matrices、pandas dataframes。
  • test_size:如果是float数据,表示测试集的占比;如果是None则默认取占比0.25;如果是int数据,则表示测试集样本个数。
  • train_size:如果是float数据,表示训练集的占比;如果是None则默认取占比0.25;如果是int数据,则表示训练集样本个数。
  • random_state:随机数种子。
  • shuffle:是否清洗数据,若false,则不清洗。
  • stratify:数据是否按Y的class分层的方式来划分,若Ture则是。例如Y的class=[‘a’,'b'],其中a占0.9、b占0.1,则划分训练集与测试集之后,训练集与测试集中a、b的占比不变。

方法return:

  一个包含分裂后训练集、测试集的列表,列表形式为[x_train,x_test,y_train,y_test,....]。

代码示例:

from sklearn.model_selection import train_test_split import numpy as np  x = np.arange(10)  # 创建一维属性x y = np.arange(10)  # 创建一维属性y  x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)  # 划分测试集与训练集  print('x_train:', x_train) print('x_test:', x_test) print('y_train:', y_train) print('y_test:', y_test)  ''' 结果: x_train: [2 0 1 7 5 9 4 8] x_test: [3 6] y_train: [2 0 1 7 5 9 4 8] y_test: [3 6] '''

2、K折交叉验证

  将数据集分为k等份,每次训练时,将其中k-1份用作训练集,单独的那一份用作测试集,依次训练K次,可以选择训练效果较好的那份或者以平均模型优度作为模型优度。

对应的类:

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

  • n_splits:几折,划分为几等分。

  • shuffle:在每次划分时,是否进行洗牌,不洗牌的话则按顺序划分。

    • 若为Falses时,其效果等同于random_state等于整数,每次划分的结果相同

    • 若为True时,每次划分的结果都不一样,表示经过洗牌,随机取样的

  • random_state:随机种子数

类的方法:

  • get_n_splits(X=None, y=None, groups=None):获取参数n_splits的值,返回交叉验证的train-test的个数。
  • split(X, y=None, groups=None):将数据集划分成训练集和测试集,返回索引生成器(即每一份样本在数据集D中的位置)。

代码示例:

from sklearn.model_selection import KFold import numpy as np  x = np.arange(12)   #创建一维属性x  fold = KFold(3) #创建3折交叉验证  for train_index, test_index in fold.split(x):     print('训练集索引:', train_index)     print('测试集索引:', test_index)     print('-------------------------------')   ''' 结果:训练集索引: [ 4  5  6  7  8  9 10 11] 测试集索引: [0 1 2 3] ------------------------------- 训练集索引: [ 0  1  2  3  8  9 10 11] 测试集索引: [4 5 6 7] ------------------------------- 训练集索引: [0 1 2 3 4 5 6 7] 测试集索引: [ 8  9 10 11] ------------------------------- '''

3、p次K折交差验证

  有时候,依次K折交叉验证不能够满足训练要求,可以进行p次,经典的例如10次10折交叉验证。

对应的类:

  sklearn.model_selection.RepeatedKFold(n_splits=5,n_repeats=2,random_state =0)

  • n_splits:几折,划分为几等分。
  • n_repeats:重复的次数,即p次K折的p。
  • random_state :随机数种子。

类的方法:

  • get_n_splits(X=None, y=None, groups=None):获取参数n_splits的值,即返回交叉验证的train-test的个数。
  • split(X, y=None, groups=None):将数据集划分成训练集和测试集,返回索引生成器(即每一份样本在数据集D中的位置)。

注意:

  RepeatedKFold在划分的时候,重复p次,每次重复会进行1次k折划分,每次划分都是随机的,这个与KFold默认方式是不同的。

代码示例:

from sklearn.model_selection import RepeatedKFold import numpy as np  x = np.arange(12)   #创建一维属性x  fold = RepeatedKFold(n_splits=3,n_repeats=2) #创建3折交叉验证  for train_index, test_index in fold.split(x):     print('训练集索引:', train_index)     print('测试集索引:', test_index)     print('-------------------------------')   '''结果:训练集索引: [ 1  2  3  4  5  8 10 11] 测试集索引: [0 6 7 9] ------------------------------- 训练集索引: [ 0  3  4  6  7  9 10 11] 测试集索引: [1 2 5 8] ------------------------------- 训练集索引: [0 1 2 5 6 7 8 9] 测试集索引: [ 3  4 10 11] ------------------------------- 训练集索引: [0 2 3 5 6 7 8 9] 测试集索引: [ 1  4 10 11] ------------------------------- 训练集索引: [ 1  4  6  7  8  9 10 11] 测试集索引: [0 2 3 5] ------------------------------- 训练集索引: [ 0  1  2  3  4  5 10 11] 测试集索引: [6 7 8 9] ------------------------------- '''

4、留一较差验证

  留一法就是Kflod的特殊形式k=1,即每次取1个样本作为测试集,其余做训练集。

对应的类:

  sklearn.model_selection.train_test_split()

类的方法:

  • get_n_splits(X=None, y=None, groups=None):返回较差验证的train-test数据对的个数。
  • split(X, y=None, groups=None):将数据集划分成训练集和测试集,返回索引生成器(即每一份样本在数据集D中的位置)。

代码示例:

from sklearn.model_selection import LeaveOneOut import numpy as np  x = np.arange(4)  # 创建一维属性x leaveoneout=LeaveOneOut()  for train,test in leaveoneout.split(x) : # 划分测试集与训练集     print('x_train:', train)     print('x_test:', test)     print('------------------------------------------------------')   ''' 结果: x_train: [1 2 3] x_test: [0] ------------------------------------------------------ x_train: [0 2 3] x_test: [1] ------------------------------------------------------ x_train: [0 1 3] x_test: [2] ------------------------------------------------------ x_train: [0 1 2] x_test: [3] ------------------------------------------------------ '''

5、留P交叉验证

  从数据集D中选P个样本作为测试集,其余作为训练集,直到选出所有的可能的P个组合为止。当P=1的时候就是留一交叉验证。

对应的类:

  sklearn.model_selection.LeavePOut(p)

  • p:测试集的样本数。

类的方法:

  • get_n_splits(X=None, y=None, groups=None):返回较差验证的train-test数据对的个数。
  • split(X, y=None, groups=None):将数据集划分成训练集和测试集,返回索引生成器(即每一份样本在数据集D中的位置)。

代码示例:

from sklearn.model_selection import LeavePOut import numpy as np  x = np.arange(4)  # 创建一维属性x leavePout=LeavePOut(2)  for train,test in leavePout.split(x) : # 划分测试集与训练集     print('x_train:', train)     print('x_test:', test)     print('------------------------------------------------------')   ''' 结果: x_train: [2 3] x_test: [0 1] ------------------------------------------------------ x_train: [1 3] x_test: [0 2] ------------------------------------------------------ x_train: [1 2] x_test: [0 3] ------------------------------------------------------ x_train: [0 3] x_test: [1 2] ------------------------------------------------------ x_train: [0 2] x_test: [1 3] ------------------------------------------------------ x_train: [0 1] x_test: [2 3] ------------------------------------------------------ '''

6、随机交叉验证

  从数据集D中随机选择样本划分训练集与测试集,可以根据需要选择需要重复几次,重复n次能获得n个train-test样本对。

对应的类:

  sklearn.model_selection.ShuffleSplit(n_splits=10, test_size=None, train_size=None, random_state=None)

  • n_splits:几折,划分为几等分。

  • test_size:如果是float数据,表示测试集的占比;如果是None则自动设置;如果是int数据,则表示测试集样本个数。
  • train_size:如果是float数据,表示训练集的占比;如果是None则自动设置;如果是int数据,则表示训练集样本个数。
  • random_state:随机种子数

类的方法:

  • get_n_splits(X=None, y=None, groups=None):返回较差验证的train-test数据对的个数。
  • split(X, y=None, groups=None):将数据集划分成训练集和测试集,返回索引生成器(即每一份样本在数据集D中的位置)。

代码示例:

from sklearn.model_selection import ShuffleSplit import numpy as np  x = np.arange(10)  # 创建一维属性x SS=ShuffleSplit(3,test_size=0.2)  for train,test in SS.split(x) : # 划分测试集与训练集     print('x_train:', train)     print('x_test:', test)     print('------------------------------------------------------')   ''' 结果: x_train: [5 3 2 9 6 8 1 7] x_test: [4 0] ------------------------------------------------------ x_train: [9 1 5 8 0 3 7 4] x_test: [6 2] ------------------------------------------------------ x_train: [4 9 3 7 5 6 2 8] x_test: [1 0] ------------------------------------------------------ '''

7、其它特殊情况的数据划分方法

2:对于分组数据来说,它的划分方法是不一样的,主要的方法有 GroupKFold,LeaveOneGroupOut,LeavePGroupOut,GroupShuffleSplit

3:对于时间关联的数据,方法有TimeSeriesSplit

三、模型评估交叉验证

  对数据集可以进行交叉验证从而建立交叉验证模型,也可以对模型的评估利用交叉验证的方法。sklearn的一些评估方法同样可以用于交叉验证。

1、模型准确度评分交叉验证

对应的方法:

  • estimator:sklearn的estimator类,即各种模型。
  • cv:几折验证,默认是3。

方法return:

  一个包含所有交叉验证的score的列表。

代码示例:

from sklearn import datasets from sklearn import svm from sklearn.model_selection import cross_val_score  iris = datasets.load_iris()  clf = svm.SVC(kernel='linear', C=1) scores = cross_val_score(clf, iris.data, iris.target, cv=5)  print(scores)   ''' 结果: [0.96666667 1.         0.96666667 0.96666667 1.        ]

2、其他评估方法交叉验证

对应方法:

  sklearn.model_selection.cross_validate(estimator, X, y=None, scoring=None, cv=’warn’,......)  

  • estimator:sklearn的estimator类,即各种模型。
  • scoring:sklearn的评估方法,可以用字典或列表方式传入。
  • cv:几折验证,默认是3。

方法return:

  一个字典,字典中每个

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!