sklearn中的交叉验证的实现(Cross-Validation)
sklearn是利用python进行机器学习中一个非常全面和好用的第三方库,用过的都说好。今天主要记录一下sklearn中关于交叉验证的各种用法,主要是对sklearn官方文档Cross-validation:evaluatingestimatorperformance进行讲解,英文水平好的建议读官方文档,里面的知识点很详细。
先导入需要的库及数据集
In[1]:importnumpyasnp In[2]:fromsklearn.model_selectionimporttrain_test_split In[3]:fromsklearn.datasetsimportload_iris In[4]:fromsklearnimportsvm In[5]:iris=load_iris() In[6]:iris.data.shape,iris.target.shape Out[6]:((150,4),(150,))
1.train_test_split
对数据集进行快速打乱(分为训练集和测试集)
这里相当于对数据集进行了shuffle后按照给定的test_size进行数据集划分。
In[7]:X_train,X_test,y_train,y_test=train_test_split( ...:iris.data,iris.target,test_size=.4,random_state=0) #这里是按照6:4对训练集测试集进行划分 In[8]:X_train.shape,y_train.shape Out[8]:((90,4),(90,)) In[9]:X_test.shape,y_test.shape Out[9]:((60,4),(60,)) In[10]:iris.data[:5] Out[10]: array([[5.1,3.5,1.4,0.2], [4.9,3.,1.4,0.2], [4.7,3.2,1.3,0.2], [4.6,3.1,1.5,0.2], [5.,3.6,1.4,0.2]]) In[11]:X_train[:5] Out[11]: array([[6.,3.4,4.5,1.6], [4.8,3.1,1.6,0.2], [5.8,2.7,5.1,1.9], [5.6,2.7,4.2,1.3], [5.6,2.9,3.6,1.3]]) In[12]:clf=svm.SVC(kernel='linear',C=1).fit(X_train,y_train) In[13]:clf.score(X_test,y_test) Out[13]:0.96666666666666667
2.cross_val_score
对数据集进行指定次数的交叉验证并为每次验证效果评测
其中,score默认是以scoring='f1_macro'进行评测的,余外针对分类或回归还有:
这需要fromsklearnimportmetrics,通过在cross_val_score指定参数来设定评测标准;
当cv指定为int类型时,默认使用KFold或StratifiedKFold进行数据集打乱,下面会对KFold和StratifiedKFold进行介绍。
In[15]:fromsklearn.model_selectionimportcross_val_score In[16]:clf=svm.SVC(kernel='linear',C=1) In[17]:scores=cross_val_score(clf,iris.data,iris.target,cv=5) In[18]:scores Out[18]:array([0.96666667,1.,0.96666667,0.96666667,1.]) In[19]:scores.mean() Out[19]:0.98000000000000009
除使用默认交叉验证方式外,可以对交叉验证方式进行指定,如验证次数,训练集测试集划分比例等
In[20]:fromsklearn.model_selectionimportShuffleSplit In[21]:n_samples=iris.data.shape[0] In[22]:cv=ShuffleSplit(n_splits=3,test_size=.3,random_state=0) In[23]:cross_val_score(clf,iris.data,iris.target,cv=cv) Out[23]:array([0.97777778,0.97777778,1.])
在cross_val_score中同样可使用pipeline进行流水线操作
In[24]:fromsklearnimportpreprocessing In[25]:fromsklearn.pipelineimportmake_pipeline In[26]:clf=make_pipeline(preprocessing.StandardScaler(),svm.SVC(C=1)) In[27]:cross_val_score(clf,iris.data,iris.target,cv=cv) Out[27]:array([0.97777778,0.93333333,0.95555556])
3.cross_val_predict
cross_val_predict与cross_val_score很相像,不过不同于返回的是评测效果,cross_val_predict返回的是estimator的分类结果(或回归值),这个对于后期模型的改善很重要,可以通过该预测输出对比实际目标值,准确定位到预测出错的地方,为我们参数优化及问题排查十分的重要。
In[28]:fromsklearn.model_selectionimportcross_val_predict In[29]:fromsklearnimportmetrics In[30]:predicted=cross_val_predict(clf,iris.data,iris.target,cv=10) In[31]:predicted Out[31]: array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,2,1,1,1,1,1,2,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2, 2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2]) In[32]:metrics.accuracy_score(iris.target,predicted) Out[32]:0.96666666666666667
4.KFold
K折交叉验证,这是将数据集分成K份的官方给定方案,所谓K折就是将数据集通过K次分割,使得所有数据既在训练集出现过,又在测试集出现过,当然,每次分割中不会有重叠。相当于无放回抽样。
In[33]:fromsklearn.model_selectionimportKFold In[34]:X=['a','b','c','d'] In[35]:kf=KFold(n_splits=2) In[36]:fortrain,testinkf.split(X): ...:printtrain,test ...:printnp.array(X)[train],np.array(X)[test] ...:print'\n' ...: [23][01] ['c''d']['a''b'] [01][23] ['a''b']['c''d']
5.LeaveOneOut
LeaveOneOut其实就是KFold的一个特例,因为使用次数比较多,因此独立的定义出来,完全可以通过KFold实现。
In[37]:fromsklearn.model_selectionimportLeaveOneOut In[38]:X=[1,2,3,4] In[39]:loo=LeaveOneOut() In[41]:fortrain,testinloo.split(X): ...:printtrain,test ...: [123][0] [023][1] [013][2] [012][3] #使用KFold实现LeaveOneOtut In[42]:kf=KFold(n_splits=len(X)) In[43]:fortrain,testinkf.split(X): ...:printtrain,test ...: [123][0] [023][1] [013][2] [012][3]
6.LeavePOut
这个也是KFold的一个特例,用KFold实现起来稍麻烦些,跟LeaveOneOut也很像。
In[44]:fromsklearn.model_selectionimportLeavePOut In[45]:X=np.ones(4) In[46]:lpo=LeavePOut(p=2) In[47]:fortrain,testinlpo.split(X): ...:printtrain,test ...: [23][01] [13][02] [12][03] [03][12] [02][13] [01][23]
7.ShuffleSplit
ShuffleSplit咋一看用法跟LeavePOut很像,其实两者完全不一样,LeavePOut是使得数据集经过数次分割后,所有的测试集出现的元素的集合即是完整的数据集,即无放回的抽样,而ShuffleSplit则是有放回的抽样,只能说经过一个足够大的抽样次数后,保证测试集出现了完成的数据集的倍数。
In[48]:fromsklearn.model_selectionimportShuffleSplit In[49]:X=np.arange(5) In[50]:ss=ShuffleSplit(n_splits=3,test_size=.25,random_state=0) In[51]:fortrain_index,test_indexinss.split(X): ...:printtrain_index,test_index ...: [134][20] [143][02] [402][13]
8.StratifiedKFold
这个就比较好玩了,通过指定分组,对测试集进行无放回抽样。
In[52]:fromsklearn.model_selectionimportStratifiedKFold In[53]:X=np.ones(10) In[54]:y=[0,0,0,0,1,1,1,1,1,1] In[55]:skf=StratifiedKFold(n_splits=3) In[56]:fortrain,testinskf.split(X,y): ...:printtrain,test ...: [236789][0145] [0134589][267] [0124567][389]
9.GroupKFold
这个跟StratifiedKFold比较像,不过测试集是按照一定分组进行打乱的,即先分堆,然后把这些堆打乱,每个堆里的顺序还是固定不变的。
In[57]:fromsklearn.model_selectionimportGroupKFold In[58]:X=[.1,.2,2.2,2.4,2.3,4.55,5.8,8.8,9,10] In[59]:y=['a','b','b','b','c','c','c','d','d','d'] In[60]:groups=[1,1,1,2,2,2,3,3,3,3] In[61]:gkf=GroupKFold(n_splits=3) In[62]:fortrain,testingkf.split(X,y,groups=groups): ...:printtrain,test ...: [012345][6789] [0126789][345] [3456789][012]
10.LeaveOneGroupOut
这个是在GroupKFold上的基础上混乱度又减小了,按照给定的分组方式将测试集分割下来。
In[63]:fromsklearn.model_selectionimportLeaveOneGroupOut In[64]:X=[1,5,10,50,60,70,80] In[65]:y=[0,1,1,2,2,2,2] In[66]:groups=[1,1,2,2,3,3,3] In[67]:logo=LeaveOneGroupOut() In[68]:fortrain,testinlogo.split(X,y,groups=groups): ...:printtrain,test ...: [23456][01] [01456][23] [0123][456]
11.LeavePGroupsOut
这个没啥可说的,跟上面那个一样,只是一个是单组,一个是多组
fromsklearn.model_selectionimportLeavePGroupsOut X=np.arange(6) y=[1,1,1,2,2,2] groups=[1,1,2,2,3,3] lpgo=LeavePGroupsOut(n_groups=2) fortrain,testinlpgo.split(X,y,groups=groups): printtrain,test [45][0123] [23][0145] [01][2345]
12.GroupShuffleSplit
这个是有放回抽样
In[75]:fromsklearn.model_selectionimportGroupShuffleSplit In[76]:X=[.1,.2,2.2,2.4,2.3,4.55,5.8,.001] In[77]:y=['a','b','b','b','c','c','c','a'] In[78]:groups=[1,1,2,2,3,3,4,4] In[79]:gss=GroupShuffleSplit(n_splits=4,test_size=.5,random_state=0) In[80]:fortrain,testingss.split(X,y,groups=groups): ...:printtrain,test ...: [0123][4567] [2367][0145] [2345][0167] [4567][0123]
13.TimeSeriesSplit
针对时间序列的处理,防止未来数据的使用,分割时是将数据进行从前到后切割(这个说法其实不太恰当,因为切割是延续性的。。)
In[81]:fromsklearn.model_selectionimportTimeSeriesSplit In[82]:X=np.array([[1,2],[3,4],[1,2],[3,4],[1,2],[3,4]]) In[83]:tscv=TimeSeriesSplit(n_splits=3) In[84]:fortrain,testintscv.split(X): ...:printtrain,test ...: [012][3] [0123][4] [01234][5]
这个repo用来记录一些python技巧、书籍、学习链接等,欢迎stargithub地址
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。