将数据集分为训练集和测试集: train_test_split()
#将数据分为train data和test data,用train data来拟合Model,用test data来评价拟合Model的优劣;
X_train,X_test,Y_train,Y_test = sklearn.model_selection.train_test_split(train_x,train_y,test_size,train_size,random_state,shuffle=True,stratify)
#return train_data and test_data
#note that: shuffle by default equals True,对于不相互独立,不服从同一分步的数据,shuffle要设为False,否则,服从同一分步的子数据集可能被同时分割到train和test数据集中,这样会造成overfitting;
#train_x为训练数据集not including label
#train_y为训练集的label
#test_size为将多少数据作为test,是一个小数
#train_size将多少数据作为train
#random_state:如果设置random_state=None,则每次shuffle都不一样,如果设置random_state=int/random_state generator,则每次shuffle都是这个seed下的结果
#shuffle:打乱数据顺序
当数据集很小时,如果将data在分割为train和test的话,则会浪费一部分数据到test,未解决这一问题,提出了一个函数,他可以评估一个estimator的given hyperparameter的好坏:cross_val_score()
sklearn.model_selection.cross_val_score(estimator,X,y=None,groups=None,scoring=None,cv=None,n_jobs=1,verbose=0,fit_params=None,pre_dispatch='2*n_jobs')
#estimator:用于拟合数据的estimator
#groups:labels for samples
#scoring:???
#cv:the number of cross validation folds
#n_jobs:用于计算的CPU数
#fit_params:estimator的参数,为dictionary的形式
#pre_dispatch:并行计算的job数
#return:cv次评分结果的array;
#note that:该函数也可以用其他的cross validation strategies,通过传递一个cross validation iterator;
#例如:
#cv = ShuffleSplit(n_splits=3, test_size=0.3, random_state=0)
#cross_val_score(clf, iris.data, iris.target, cv=cv)
data transformation with held out data
将data分为train,test,再用train进行model拟合之前,如果对train进行了normalize动作,则在预测test之前,也应该使用同样的参数对test进行normalize;
way1:
from sklearn import preprocessing
X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.4, random_state=0)
scaler = preprocessing.StandardScaler().fit(X_train)
X_train_transformed = scaler.transform(X_train)
clf = svm.SVC(C=1).fit(X_train_transformed, y_train)
X_test_transformed = scaler.transform(X_test)
clf.score(X_test_transformed, y_test)
way2:利用pipeline
>>> from sklearn.pipeline import make_pipeline
>>> clf = make_pipeline(preprocessing.StandardScaler(), svm.SVC(C=1))
>>> cross_val_score(clf, iris.data, iris.target, cv=cv)
cross_val_score()与cross_validate()区别
cross_val_score()只允许用一个scoring参数,cross_validate()允许用多个,其返回值是一个字典,key为评估指标,value为评估指标值,如fit_time,test_score等;note that:在cross_validate()中scoring参数可以是string,list,dictionary;
from sklearn.model_selection import cross_validate
from sklearn.metrics import recall_score
from sklearn.metrics.scorer import make_scorer
#scoring的几种形式
scoring = ['precision_macro', 'recall_macro']
scoring = {'prec_macro': 'precision_macro', 'rec_micro': make_scorer(recall_score, average='macro')}
scores = cross_validate(clf, iris.data, iris.target,scoring='precision_macro')
#cross_validate()应用
clf = svm.SVC(kernel='linear', C=1, random_state=0)
scores = cross_validate(clf, iris.data, iris.target, scoring=scoring, cv=5, return_train_score=False)
sorted(scores.keys())
#output:['fit_time', 'score_time', 'test_precision_macro', 'test_recall_macro']
scores['test_recall_macro']
#output:array([ 0.96..., 1. ..., 0.96..., 0.96..., 1. ])
#具体scoring的内容???
cross_val_predict():当数据中的每个样本都仅被分配到test集一次,则可用cross_val_predict()求得各个test中的sample的预测值;
sklearn.model_selection.cross_val_predict(estimator,data_x,data_y,cv=None,method='predict')
#method:为estimator的方法名,如:predict_proba
#其它参数与cross_val_score()的参数一样
示例:
from sklearn.model_selection import cross_val_predict
predicted = cross_val_predict(clf, iris.data, iris.target, cv=10)
metrics.accuracy_score(iris.target, predicted)
cross validation iterators
iterators for identically distributed data
假设数据集的样本之间互相独立,且服从均衡分布,则可用下列iterator。
值得一提的是,在实际中,上述假设很少成立,有的数据集分布可能与时间有关,有的数据集可能存在多个分布,这些数据集最好用相应的corss validation iterator处理,下面将介绍;
- KFold
kf = sklearn.model_selection.KFold(n_splits=3,shuffle=False,random_state=None)
#n_splits为folds数量
kf.get_n_splits([data_X,data_y,groups]) # KFold的一个方法,返回cv的次数n_splits
kf.split(data_X[,data_y,groups]) #返回iterator of (train indice,test indice)
- RepeatedKFold
与KFold的唯一区别在于,RepeatedKFold执行KFold n_repeats次
sklearn.model_selection.RepeatedKFold(n_splits=5,n_repeats=10,random_state=None)
#n_repeats:为重复执行KFold的次数
#其method与KFold相同
- LeaveOneOut
LeaveOneOut即cv=the number of sample 的KFold,其缺点有:计算量很大,因为每次cv训练集样本量为n-1;在着,通过该函数计算的variance 较大;
建议,一般使用cv=5 or 10 的KFold即可;
sklearn.model_selection.LeaveOneOut
x = LeaveOneOut()
x.get_n_splits(data)
x.split(data)
#LeaveOneOut的method与KFold相同
- LeavePOut
sklearn.model_selection.LeavePOut(p)
#p:test set的数量,该函数可得的(train indice,test indice)tuple为C{n,p}
#method与KFold一样
- ShuffleSplit
在split数据之前,会先shuffle数据,且,与KFold的一个显著不同是,他能通过参数n_splits控制iteration的次数(即split的次数)
sklearn.model_selection.ShuffleSplit(n_splits=10,test_size='default',train_size=None,random_state=None)
#n_splits:为iteration的次数
#method与KFold一样
对于cross_validation来讲,cv=5 or 10较为合适
cross validation iterators with stratification based on class labels
在实际中,有一些这样的数据集,其各个label的比例在整个数据集中很不均衡,为了保证cross validation中train,test data保有原始数据集的label比例,我们可以用如下的cv iterator;
- StratifiedKFold
默认为不shuffle数据
sklearn.model_selection.StratifiedKFold(n_splits=3,shuffle=False,random_state=None)
# n_splits : folds数量
# method与KFold相同
- RepeatedStratifiedKFold
在split数据之前,不shuffle数据
sklearn.model_selection.RepeatedStratifiedKFold(n_splits=5,n_repeats=10,random_state=None)
#n_repeats:cv执行的次数
#与KFold method 相同
- StratifiedShuffleSplit
在split数据之前,先shuffle数据
sklearn.model_selection.StratifiedShuffleSplit(n_splits=10,test_size='default',train_size=None,random_state=None)
#n_splits:iteration次数
#与KFold method一样
cross validation iterators for grouped data
对于一个数据集,可能有几组不同的数据,每组数据服从不同的分布,在对其进行cv的时候,应该注意同一组的数据只能分到train或test数据集,否则的话,会Overfitting数据,不利于将来未知组 数据的预测。
举个例子,一组医疗数据,其中每一小撮数据来自一个人,在进行cv时,要将同一个人的数据完全分到train或test数据集中。这样不至于造成overfitting,在预测 未知person的数据时,得到的预测结果精度更高;
- GroupKFold
sklearn.model_selection.GroupKFold(n_splits=3)
#n_splits:folds的数目
#method与KFold相同
- LeaveOneGroupOut
sklearn.model_selection.LeaveOneGroupOut
#method与KFold相同
-LeavePGroupsOut
sklearn.model_selection. LeavePGroupsOut(n_groups)
#method与KFold相同
- GroupShuffleSplit
sklearn.model_selection.GroupShuffleSplit(n_splits=5,test_size='default',train_size=None,random_state=None)
#n_splits:Iteration次数
#method与KFold相同
Cross validation of time series
数据的分布与时间有关,如不同年份的数据服从不同的分布,因此,如group data一样,也应将同一年份的数据完全分到train或者test中,以防止Overfitting;
sklearn.model_selection.TimeSeriesSplit(n_splits=3,max_train_size=None)
#n_splits:folds数目
#max_train_size:一次training中,train data的最大值
#method与KFold相同
Predefined Fold-split/Validation-set
通过参数指定那些sample称为test,或那些sample不包含在train、test中
sklearn.model_selection.PredefinedSplit(test_fold)
#test_fold:array_like(shape=n_samples),value:1:包含在test中,0:不包含在test中,-1:不包含在train或者test中
#method与KFold相同
Note that:
如果数据的排列有一定规则,比如,同一个label的数据连续排列,那么在进行数据split前,应该先shuffle以下;
如果数据不是相互独立,不同的subset服从不同的分布,则split前不应该进行shuffle操作;