交叉验证——sklearn.model_selection.KFold

 

 

 

最近使用python进行数据集的划分。使用到了交叉验证(Cross-validation),需要整理sklearn.model_selection.KFold函数的参数设定和使用实例。整理如下:

 

1、Cross-validation 交叉验证 

附注:官方文档链接:https://scikit-learn.org/dev/modules/cross_validation.html#cross-validation

交叉验证的基本思想:把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set or test set),首先用训练集对模型进行训练(可以使用不同的机器学习训练方法),得到相应模型(如模型A)。再利用验证集来测试模型(A)的泛化误差。另外,现实中数据总是有限的,为了对数据形成重用,从而提出k-折叠交叉验证。下图为网上传播较多的5折交叉验证图示。

5折交叉验证-图源网络

对回归问题或者分类问题,经过k折交叉验证之后,计算k次求得的分类率的平均值,作为该模型或者假设函数的真实分类率。Cross-validation能有效的避免过学习以及欠学习状态的发生,结果也比较具有说服性。

 

2、sklearn.model_selection.StratifiedKFold 函数使用

官方文档链接:https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.html

StratifiedKFold 函数。分层K-Folds交叉验证器,提供训练/测试索引以分割训练/测试集中的数据。此交叉验证对象是KFold的变体,可返回分层折叠。 通过保留每个类别的样本百分比来进行折叠。

1)参数

n_splits:折叠数量,表示划分成几份。 必须至少2。版本0.20更改:n_splits默认值将在v0.22中从3更改为5。

shuffle:布尔值,可选。 是否在划分之前对每个类的样本进行洗牌。

①若为Falses时,其效果等同于random_state等于整数,每次划分的结果相同

②若为True时,每次划分的结果都不一样,表示经过洗牌,随机取样的

random_state:随即种子。int,RandomState实例或None,默认=无。
   如果是int,则random_state是随机数生成器使用的种子; 如果是RandomState实例,则random_state是随机数生成器; 如果为None,则随机数生成器是np.random使用的RandomState实例。 在shuffle == True时使用。

 

2)工具函数

get_n_splits(self[, X, y, groups])返回交叉验证器中的拆分迭代次数
split(self, X, y[, groups])将数据拆分为训练和测试集,返回索引值

X: 矩阵,(n_samples,n_features)。训练数据,其中n_samples是样本数,n_features是特征数。

      注意,提供y足以生成分割,因此np.zeros(n_samples)可以用作X的占位符而不是实际训练数据。

   y: 矩阵,(n_samples,)。监督学习问题的目标变量,标签值。 

   groups:对象。

 

3)以下为划分代码实例

eg1:划分之后不洗牌,shuffle=False,运行两次,结果相同。

调用形式为:StratifiedKFold(n_splits=3, shuffle=False, random_state=None)

import numpy as np
from sklearn.model_selection import StratifiedKFold
X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
y = np.array([0, 0, 1, 1])
skf = StratifiedKFold(n_splits=2)
skf.get_n_splits(X, y)

print(skf)  

for train_index, test_index in skf.split(X, y):
   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]

运行结果如下,将X(4行2列,每一行的编号为0,1,2,3),进行2折划分,就是将数据集划分2次,每次将其分为小train和小test两部分。

第一次划分数据集结果为:1,3行为小train;0,2行为小test。

第二次划分数据集结果为:0,2行为小train;1,3行为小test。

#第一次运行程序结果
StratifiedKFold(n_splits=2, random_state=None, shuffle=False)
TRAIN: [1 3] TEST: [0 2]
TRAIN: [0 2] TEST: [1 3]


#第二次运行程序结果,因为未洗牌,所以结果相同
StratifiedKFold(n_splits=2, random_state=None, shuffle=False)
TRAIN: [1 3] TEST: [0 2]
TRAIN: [0 2] TEST: [1 3]

eg2:划分后洗牌,shuffle=True,运行两次,结果不同。

import numpy as np
from sklearn.model_selection import StratifiedKFold
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8],[9, 10], [11, 12],[13, 14], [15, 16]])
y = np.array([0, 0, 1, 1,0, 0, 1, 1])

# //K折划分,就是将数据集划分k次,每次将其分为小train和小test两部分。如果数据集行数可以被k整除,那么小test的行数就为被整除后的一份
skf = StratifiedKFold(n_splits=4,shuffle=True)
#获得划分的次数并且打印,就是n_splits
print(skf.get_n_splits(X, y))

print(skf)

for train_index, test_index in skf.split(X, y):
   print("TRAIN:", train_index, "TEST:", test_index)
   # 生成小train,小test。X为样本(行)+特征(列)矩阵,y为标签向量
   X_train, X_test = X[train_index], X[test_index]
   y_train, y_test = y[train_index], y[test_index]

结果

#第一次运行结果
4
StratifiedKFold(n_splits=4, random_state=None, shuffle=True)
TRAIN: [0 1 2 3 5 7] TEST: [4 6]
TRAIN: [0 2 4 5 6 7] TEST: [1 3]
TRAIN: [1 3 4 5 6 7] TEST: [0 2]
TRAIN: [0 1 2 3 4 6] TEST: [5 7]

#第二次运行结果,因为设置划分一次数据集之后进行洗牌,所以结果不一样
4
StratifiedKFold(n_splits=4, random_state=None, shuffle=True)
TRAIN: [1 2 4 5 6 7] TEST: [0 3]
TRAIN: [0 1 2 3 5 7] TEST: [4 6]
TRAIN: [0 3 4 5 6 7] TEST: [1 2]
TRAIN: [0 1 2 3 4 6] TEST: [5 7]

 

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`sklearn.model_selection`是Scikit-learn库中用于模型选择和评估的模块。它提供了一系列用于交叉验证、参数调优、数据集划分等常用的工具函数和类,使得我们能够更加方便地进行模型选择和评估。具体包括以下内容: 1. `train_test_split`: 数据集划分函数,用于将数据集划分为训练集和测试集。 2. `KFold`: K折交叉验证生成器,用于将数据集划分为K份,每次使用其中K-1份作为训练集,1份作为验证集,进行K次交叉验证。 3. `StratifiedKFold`: 分层K折交叉验证生成器,用于解决数据集中类别不平衡问题。 4. `GridSearchCV`: 网格搜索与交叉验证结合的参数调优器,用于寻找最优超参数组合。 5. `RandomizedSearchCV`: 随机搜索与交叉验证结合的参数调优器,可以在参数空间中随机采样一定数量的超参数组合进行训练和评估。 6. `cross_val_score`: 交叉验证评估函数,用于对模型进行K折交叉验证,并返回K次验证的评分结果。 7. `learning_curve`: 学习曲线生成器,用于分析模型在不同大小的训练集上的表现。 8. `validation_curve`: 验证曲线生成器,用于分析模型在不同超参数取值下的表现。 优化前的代码如下: ```python from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV from sklearn.svm import SVC X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) params = {'C': [0.1, 1, 10], 'kernel': ['linear', 'rbf']} svc = SVC() clf = GridSearchCV(svc, params) clf.fit(X_train, y_train) print(clf.score(X_test, y_test)) ``` 这段代码的问题在于没有使用交叉验证来评估模型性能,只是将数据集简单地划分为训练集和测试集进行评估。这种方式容易造成模型性能估计不准确的问题。 针对这个问题,我们可以使用`cross_val_score`函数来进行交叉验证评估。同时,还可以使用`Pipeline`类将数据预处理和模型训练过程结合起来,方便实现一系列数据预处理和特征工程操作。 优化后的代码如下: ```python from sklearn.model_selection import cross_val_score from sklearn.model_selection import GridSearchCV from sklearn.pipeline import Pipeline from sklearn.svm import SVC from sklearn.preprocessing import StandardScaler pipe = Pipeline([('scaler', StandardScaler()), ('svc', SVC())]) params = {'svc__C': [0.1, 1, 10], 'svc__kernel': ['linear', 'rbf']} clf = GridSearchCV(pipe, params, cv=5) scores = cross_val_score(clf, X, y, cv=5) print('Accuracy: %0.3f (+/- %0.3f)' % (scores.mean(), scores.std() * 2)) ``` 优化说明: 1. 使用`Pipeline`类将数据预处理和模型训练过程结合起来,方便实现一系列数据预处理和特征工程操作。 2. 使用`cross_val_score`函数进行交叉验证评估,避免了模型性能估计不准确的问题。 3. 指定了`GridSearchCV`中的交叉验证折数为5,使得模型可以更加准确地评估性能。 4. 在`GridSearchCV`中指定了`svc__C`和`svc__kernel`参数,表示需要对SVM的惩罚参数C和核函数类型进行调优。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值