赞
踩
交叉验证存在的原因:
在建模时,经常会遇到这样的情况:模型在训练样本集上拟合成功后的性能评价指标都表现较好,但在测试样本集上的验证效果却表现很差,这种偏差情况出现的原因,往往是模型出现了过拟合问题。
当然,这种现象在实际建模场景中是很常见的,但为了得到一个满足业务需求且性能效果可用的模型,我们必然会采取有效的措施来解决这类问题。在这种建模实际业务场景下,交叉验证的思想方法便发挥了很重要的作用,从本质上来讲,交叉验证可以充分使用所有的训练数据用于评估模型,这为模型最终的稳定输出设定了良好的条件。
- from sklearn import linear_model,datasets
- import pandas as pd
- iris=datasets.load_iris()#加载数据集
-
- train=pd.DataFrame(iris.data,columns=iris.feature_names)#建立样本
- target=pd.DataFrame(iris.target,columns=['target'])#设置样本标签
-
HoldOut交叉验证,是将整个数据集按照一定比例随机划分为训练集和验证集。在实际情景中,训练集与验证集的拆分比例一般为7:3或8:2。
这种方法是最基础的也是最简单的交叉验证方法,由于在每次构建模型过程中,模型训练集上仅拟合一次,因此任务执行速度很快,但为了保证模型相对稳定,往往可以多次对数据进行拆分并训练模型,最后从中选择性能表现较优模型。
在Python语言中,HoldOut交叉验证可通过调用函数train_test_split( )来选取数据。
- #方法1:HoldOut交叉验证
- from sklearn.model_selection import train_test_split
- from sklearn.linear_model import LogisticRegression
- from sklearn.metrics import accuracy_score
-
- model=LogisticRegression()#l逻辑回归模型
- train_x,test_x,train_y,test_y=train_test_split(train,target,test_size=0.3,random_state=0)#训练集验证集7:3的比例划分
-
- model.fit(train_x,train_y)
-
- acc_train=accuracy_score(train_y,model.predict(train_x)) #accuracy_score():用于计算准确率
- acc_test=accuracy_score(test_y,model.predict(test_x))
-
- print('train score :{},test acore:{}'.format(acc_train,acc_test))
K折交叉验证(K-Fold)的思想是将整个样本数据集拆分为K个相同大小的子样本,每个分区样本可以称为一个“折叠”,因此拆分后的样本数据可理解为K折。
其中,某任意1折数据作为验证集,而其余K-1折数据相应作为作训练集。在交叉验证过程中,训练集与验证集的交替会重复K次,也就是每个折叠的分区样本数据都会作为验证集,其他折叠的数据作为训练集。
模型训练后的最终精度评估,可以通过取K个模型在对应验证数据集上的平均精度。在Python语言中,K折交叉验证可通过调用函数cross_val_score( )与KFold( )来选取数据。
- #方法1:K折交叉验证
- from sklearn.model_selection import cross_val_score,KFold
- from sklearn.linear_model import LogisticRegression
- from sklearn.metrics import accuracy_score
-
- model=LogisticRegression()#l逻辑回归模型
-
- #k折交叉验证
- kf=KFold(n_splits=5)#5折交叉验证
-
- model.fit(train_x,train_y)
-
- score=cross_val_score(model,train,target,cv=kf)
-
- print('kf score :{},kf acore mean:{}'.format(score,score.mean()))
分层K折交叉验证,主要原理逻辑与K折交叉验证是类似的,仍然是将整个样本数据集拆分为K个部分,最关键的区别是分层K折交叉验证通过对目标变量的分层抽样,使得每个折叠数据集的目标变量分布比例,与整个样本数据的目标比例保持一致,有效解决样本不均衡的情况,因此是K折交叉验证的优化版,且更能满足实际业务场景的需求。
分层的意思是说在每一折中都保持着原始数据中各个类别的比例关系,比如说:原始数据有A、B、C3类,比例为1:2:1,采用3折分层交叉验证,那么划分的3折中,每一折中A、B、C的数据类别保持着1:2:1的比例,这样的验证结果更加可信。
在Python语言中,分层K折交叉验证可通过调用函数cross_val_score( )与StratifiedKFold( )来选取数据。
- #方法3:分层K折交叉验证
- from sklearn.model_selection import cross_val_score,StratifiedKFold
- from sklearn.linear_model import LogisticRegression
- from sklearn.metrics import accuracy_score
-
- model=LogisticRegression()#l逻辑回归模型
-
- #k折交叉验证
- kf=StratifiedKFold(n_splits=5)#5折交叉验证
-
- model.fit(train_x,train_y)
-
- score=cross_val_score(model,train,target,cv=kf)
-
- print('kf score :{},kf acore mean:{}'.format(score,score.mean()))
蒙特卡罗交叉验证,也称为Shuffle Split交叉验证,是一种非常灵活的交叉验证策略。在这种技术中,数据集被随机划分为训练集和验证集。
在数据随机拆分的过程中,可以指定训练集与验证集的样本占比大小,二者比例之和没有必须为100%的要求。如果训练集和验证集大小的增加百分比总和不是 100,则剩余的数据集不会用于训练集或验证集。假设我们有 100 个样本,其中 60% 的样本用作训练集,20% 的样本用作验证集,那么剩下的 20%( 100-(60+20)) 将不被使用。这种拆分将重复我们必须指定的“n”次。
在Python语言中,Shuffle-Split交叉验证可通过调用函数cross_val_score( )与ShuffleSplit( )来选取数据。
- #方法4:Shuffle-Split交叉验证
- from sklearn.model_selection import cross_val_score,ShuffleSplit
- from sklearn.linear_model import LogisticRegression
- from sklearn.metrics import accuracy_score
-
- model=LogisticRegression()#l逻辑回归模型
-
- model.fit(train_x,train_y)
- shuffl=ShuffleSplit(train_size=0.6,test_size=0.2,n_splits=10) #重复n次
- score=cross_val_score(model,train,target,cv=shuffl)
-
- print('kf score :{},kf acore mean:{}'.format(score,score.mean()))
Leave-P-Out交叉验证,是通过指定p值后,p个样本作为验证集,剩余n-p个样本作为训练集,然后不断重复这个过程,直到整个样本数据都作为验证集,这种方法的缺点是任务耗时较长,相比前几种方法应用相对较少。
假设我们在数据集中有 100 个样本。如果我们使用 p=10,那么在每次迭代中,10 个值将用作验证集,其余 90 个样本将用作训练集。
重复这个过程,直到整个数据集在 p 样本和 n-p 训练样本的验证集上被划分。
在Python语言中,Leave-P-Out交叉验证可通过调用函数cross_val_score( )与LeavePOut( )来选取数据。
- #方法5:Leave-P-Out交叉验证
- from sklearn.model_selection import cross_val_score,LeavePOut
- from sklearn.linear_model import LogisticRegression
- from sklearn.metrics import accuracy_score
-
- model=LogisticRegression()#l逻辑回归模型
- model.fit(train_x,train_y)
-
- lpo=LeavePOut(p=20) #指定p=20,即选取20个样本
- lpo.get_n_splits(train_x)
-
- score=cross_val_score(model,train,target,cv=lpo)
-
- print('kf score :{},kf acore mean:{}'.format(score,score.mean()))
结果太慢了就不贴了
时间序列数据是在不同时间点收集的数据。由于数据点是在相邻时间段收集的,因此观测值之间可能存在相关性。这是区分时间序列数据与横截面数据的特征之一。
在时间序列数据的情况下如何进行交叉验证?
在时间序列数据的情况下,我们不能选择随机样本并将它们分配给训练集或验证集,因为使用未来数据中的值来预测过去数据的值是没有意义的。
由于数据的顺序对于时间序列相关问题非常重要,所以我们根据时间将数据拆分为训练集和验证集,也称为“前向链”方法或滚动交叉验证。
我们从一小部分数据作为训练集开始。基于该集合,我们预测稍后的数据点,然后检查准确性。
然后将预测样本作为下一个训练数据集的一部分包括在内,并对后续样本进行预测。
- import numpy as np
- from sklearn.model_selection import TimeSeriesSplit
- X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]])
- y = np.array([1, 2, 3, 4, 5, 6])
- time_series = TimeSeriesSplit()
- print(time_series)
- for train_index, test_index in time_series.split(X):
- print("TRAIN:", train_index, "TEST:", test_index)
- X_train, X_test = X[train_index], X[test_index]
- y_train, y_test = y[train_index], y[test_index]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。