数据集划分方法(留出法、交叉验证)

一、留出法

    留出法(hold_out)直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T,即 D = S ⋃ T , S ⋂ T = ∅ D=S\bigcup T,S\bigcap T=\emptyset D=ST,ST=,在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的估计。

举例:

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

cancer = load_breast_cancer()
X_train,X_test,y_train,y_test = train_test_split(cancer.data,cancer.target,random_state=0)

logreg = LogisticRegression().fit(X_train,y_train)
print("Test set score:{:.2f}".format(logreg.score(X_test,y_test)))

输出:

output: Test set score:0.96

缺点如下:

  • 缺点一:浪费数据
  • 缺点二:容易过拟合,且矫正方式不方便

    这时,我们需要使用另外一种分割方式-交叉验证 或者 留P法(leave P out)

二、留一法(LOO)或留P法(LPO)

    LOO : 对于整个数据集而言,每次选取一个样本作为验证集,其余样本作为训练集

    LPO : 对于整个数据集而言,每次选取P个样本作为验证集,其余样本作为训练集

    LOO的好处在于,避免的数据的浪费,但是同时也拥有了,更高的性能开销

    一般LOO相对于 K-Fold 而言,拥有更高的方差,但是对于方差占主导的情况时,LOO可能拥有比交叉验证更强的能力.

留一法举例:

方法一

from sklearn.datasets import load_iris
from sklearn.model_selection import LeaveOneOut,cross_val_score
from sklearn.linear_model import LogisticRegression

iris = load_iris()
print('Iris labels:\n{}'.format(iris.target))
logreg = LogisticRegression()
loout = LeaveOneOut()
scores = cross_val_score(logreg,iris.data,iris.target,cv=loout)
print("leave-one-out cross validation scores:{}".format(scores))
print("Mean score of leave-one-out cross validation:{:.2f}".format(scores.mean()))

输出:

Iris labels:
[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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
leave-one-out cross validation scores:[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. 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. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 1. 0. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 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. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 1. 0. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1.]
Mean score of leave-one-out cross validation:0.95

方法二

from sklearn.model_selection import train_test_split,LeaveOneOut,LeavePOut
from sklearn import datasets
from sklearn import svm
from sklearn.metrics import accuracy_score
import numpy as np

iris = datasets.load_iris()
clf_svc = svm.SVC(kernel='linear')

loo = LeaveOneOut()
loo.get_n_splits(iris.data)
mean_accuracy_score_list = []
for train_index, test_index in loo.split(iris.data):
    clf_svc.fit(iris.data[train_index], iris.target[train_index])
    prediction = clf_svc.predict(iris.data[test_index])
    mean_accuracy_score_list.append(accuracy_score(iris.target[test_index], prediction))
print(np.average(mean_accuracy_score_list))

输出:

0.98

三、交叉验证(Standard 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方法,数据划分具有偶然性;交叉验证通过多次划分,大大降低了这种由一次随机划分带来的偶然性,同时通过多次划分,多次训练,模型也能遇到各种各样的数据,从而提高其泛化能力;

  • 与原始的train_test_split相比,对数据的使用效率更高。train_test_split,默认训练集、测试集比例为3:1,而对交叉验证来说,如果是5折交叉验证,训练集比测试集为4:1;10折交叉验证训练集比测试集为9:1。数据量越大,模型准确率越高!

缺点:

  • 这种简答的交叉验证方式,从上面的图片可以看出来,每次划分时对数据进行均分,设想一下,会不会存在一种情况:数据集有5类,抽取出来的也正好是按照类别划分的5类,也就是说第一折全是0类,第二折全是1类,等等;这样的结果就会导致,模型训练时,没有学习到测试集中数据的特点,从而导致模型得分很低,甚至为0,!为了避免这种情况,又出现了其他的各种交叉验证方式。

举例:

from sklearn.model_selection import cross_val_score

logreg = LogisticRegression()
scores = cross_val_score(logreg,cancer.data, cancer.target) #cv:默认是3折交叉验证,可以修改cv=5,变成5折交叉验证。
print("Cross validation scores:{}".format(scores))
print("Mean cross validation score:{:2f}".format(scores.mean()))

输出:

Cross validation scores:[0.93684211 0.96842105 0.94179894]
Mean cross validation score:0.949021

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

    分层交叉验证(Stratified k-fold cross validation):首先它属于交叉验证类型,分层的意思是说在每一折中都保持着原始数据中各个类别的比例关系,比如说:原始数据有3类,比例为1:2:1,采用3折分层交叉验证,那么划分的3折中,每一折中的数据类别保持着1:2:1的比例,这样的验证结果更加可信。

    通常情况下,可以设置cv参数来控制几折,但是我们希望对其划分等加以控制,所以出现了KFold,KFold控制划分折,可以控制划分折的数目,是否打乱顺序等,可以赋值给cv,用来控制划分。
在这里插入图片描述
举例:

from sklearn.datasets import load_iris
from sklearn.model_selection import StratifiedKFold,cross_val_score
from sklearn.linear_model import LogisticRegression

iris = load_iris()
print('Iris labels:\n{}'.format(iris.target))
logreg = LogisticRegression()
strKFold = StratifiedKFold(n_splits=3,shuffle=False,random_state=0)
scores = cross_val_score(logreg,iris.data,iris.target,cv=strKFold)
print("straitified cross validation scores:{}".format(scores))
print("Mean score of straitified cross validation:{:.2f}".format(scores.mean()))

输出:

Iris labels:
[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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
straitified cross validation scores:[0.96078431 0.92156863 0.95833333]
Mean score of straitified cross validation:0.95

五、Shuffle-split cross-validation

    控制更加灵活:可以控制划分迭代次数、每次划分时测试集和训练集的比例(也就是说:可以存在既不在训练集也不再测试集的情况)
在这里插入图片描述
举例:

from sklearn.datasets import load_iris
from sklearn.model_selection import ShuffleSplit,cross_val_score
from sklearn.linear_model import LogisticRegression

iris = load_iris()
shufspl = ShuffleSplit(train_size=.5,test_size=.4,n_splits=8) #迭代8次;
logreg = LogisticRegression()
scores = cross_val_score(logreg,iris.data,iris.target,cv=shufspl)

print("shuffle split cross validation scores:\n{}".format(scores))
print("Mean score of shuffle split cross validation:{:.2f}".format(scores.mean()))

输出:

shuffle split cross validation scores:
[0.95      0.95      0.95      0.95      0.93333333 0.96666667
0.96666667 0.91666667]
Mean score of shuffle split cross validation:0.95

参考

https://blog.csdn.net/fontthrone/article/details/79219663
https://blog.csdn.net/FontThrone/article/details/79220127
https://blog.csdn.net/qq_37007384/article/details/88418256

  • 7
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值