交叉验证

train_test_split
在分类问题中,我们通常通过对训练集进行train_test_split,划分成train 和test 两部分,其中train用来训练模型,test用来评估模型,模型通过fit方法从train数据集中学习,然后调用score方法在test集上进行评估,打分;从分数上我们可以知道 模型当前的训练水平如何。
然而,这种方式存:只进行了一次划分,数据结果具有偶然性,如果在某次划分中,训练集里全是容易学习的数据,测试集里全是复杂的数据,这样就会导致最终的结果不尽如意;反之,亦是如此。
因为没有测试集,所以先把训练集抽出来一些做测试集,一些做训练集,这是一次性的行为,接着,对我们的训练接进行cv折的交叉验证,得到分数, 选择分数最高的参数,然后最后在在测试集上看分数

from sklearn import datasets	#自带数据集
from sklearn.model_selection import train_test_split,cross_val_score	#划分数据 交叉验证
from sklearn.neighbors import KNeighborsClassifier  #一个简单的模型,只有K一个参数,类似K-means
import matplotlib.pyplot as plt
iris = datasets.load_iris()		#加载sklearn自带的数据集
X = iris.data 			#这是数据
y = iris.target 		#这是每个数据所对应的标签
train_X,test_X,train_y,test_y = train_test_split(X,y,test_size=1/3,random_state=3)	
#这里划分数据以1/3的来划分 训练集训练结果 测试集测试结果
k_range = range(1,31)
cv_scores = []		#用来放每个模型的结果值
for n in k_range:
    knn = KNeighborsClassifier(n)   #knn模型,这里一个超参数可以做预测,当多个超参数时需要使用另一种方法GridSearchCV
    scores = cross_val_score(knn,train_X,train_y,cv=10,scoring='accuracy') 
    #cv:选择每次测试折数  accuracy:评价指标是准确度,可以省略使用默认值,具体使用参考下面。
    cv_scores.append(scores.mean())
plt.plot(k_range,cv_scores)
plt.xlabel('K')
plt.ylabel('Accuracy')		#通过图像选择最好的参数
plt.show()
best_knn = KNeighborsClassifier(n_neighbors=3)	# 选择最优的K=3传入模型
best_knn.fit(train_X,train_y)			#训练模型
print(best_knn.score(test_X,test_y))	#看看评分

cross_val_score用来做交叉验证,里面的一个参数cv的选择比较悬疑,有时会用cv=n,有时又用cv=KFold(n_splits=n)。

查来查去,在《machine learning》终于找到了一个说法:

When an integer is passed to the cv parameter of cross_val_score():

StratifiedKFold is used if the estimator is a classifier and y is either binary or multiclass.
In all other cases, KFold is used.
啥意思?还是翻译一下:如果估计器是一个分类器,并且y是二进制或多类,则使用StratifiedKFold,如果是其他情况,就用KFold

这里的StratifiedKFold是啥?cv=StratifiedKFold(n_splits=5)其实就等价于cv=5
http://blog.sina.com.cn/s/blog_7103b28a0102w70h.html几种CV方法的生成策略
2 几种不同的CV策略生成器

前面提到,cross_val_score中的参数cv可以接受不同的CV策略生成器作为参数,以此使用不同的CV算法。这里介绍几种sklearn中的CV策略生成器函数

2.1 K-fold

最基础的CV算法,也是默认采用的CV策略​。主要的参数包括两个,一个是样本数目,一个是k-fold要划分的份数。

​2.2 Stratified k-fold

​与k-fold类似,将数据集划分成k份,不同点在于,划分的k份中,每一份内各个类别数据的比例和原始数据集中各个类别的比例相同。

​2.3 Leave-one-out

​参数只有一个,即样本数目。

​2.4 Leave-P-out

每次从整体样本中去除p条样本作为测试集,如果共有n条样本数据,那么会生成

个训练集/测试集对。和LOO,KFold不同,这种策略中p个样本中会有重叠。

2.5 Leave-one-label-out

​​​这种策略划分样本时,会根据第三方提供的整数型样本类标号进行划分。每次划分数据集时,取出某个属于某个类标号的样本作为测试集,剩余的作为训练集。

​2.6 Leave-P-Label-Out

与Leave-One-Label-Out类似,但这种策略每次取p种类标号的数据作为测试集,其余作为训练集。

[cross_val_score中cv=5与cv=KFold(n_splits=5)的区别]
果如上图,仔细看看会发现第一个和第三个的结果一模一样,这也证明了“cv=StratifiedKFold(n_splits=5)其实就等价于cv=5”

上面都是纸上谈兵,直接实操一下看看结果。

我在泰坦尼克预测案例中,用了随机森林来玩,估计器是分类器,并且Y是二进制值,按照上面的结论,这里应该用cv=3(或者cv=StratifiedKFold(n_splits=3))最合适。跑完结果发现,cv=3的结果确实优于cv=kf的结果
https://blog.csdn.net/qq_22592457/article/details/103584053(https://blog.csdn.net/qq_22592457/article/details/103584053)
在这里插入图片描述

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import KFold,cross_val_score,StratifiedKFold
alg=RandomForestClassifier(random_state=1,n_estimators=10,min_samples_leaf=1,min_samples_split=2)
kf=KFold(n_splits=3,random_state=1)
score1=cross_val_score(alg,X,y,cv=3)
score2=cross_val_score(alg,X,y,cv=kf)
score3=cross_val_score(alg,X,y,cv=StratifiedKFold(n_splits=3))
print("score1=",score1,"score2=",score2,"score3=",score3)

score1= [0.78114478 0.82491582 0.79461279] score2= [0.78114478 0.8013468 0.79461279] score3= [0.78114478 0.82491582 0.79461279]

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import KFold,cross_val_score,StratifiedKFold
alg=RandomForestClassifier(random_state=1,n_estimators=10,min_samples_leaf=1,min_samples_split=2)
kf=KFold(n_splits=3,random_state=1)
score1=cross_val_score(alg,X,y,cv=3)#能够给出这个参数构造的模型的分数,根据评价函数得出的分数,根据分数高低来选择最优的参数
score2=cross_val_score(alg,X,y,cv=kf)#因为默认是准确率为scoring参数,所以得到的分数就是准确率
score3=cross_val_score(alg,X,y,cv=StratifiedKFold(n_splits=3))
print("score1=",score1,"score2=",score2,"score3=",score3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值