在sklearn.model_selection.GridSearchCV中使用自定义验证集进行模型调参

本文链接:http://blog.csdn.net/ismarvellous/article/details/78195010

模型调参是一门玄学。为了获得模型最优参数,我们需要不断地尝试不同的参数,这一过程相当繁琐。好在python的sklearn包中为我们提供了GridSearchCV,大大方便了调参过程。本文使用实际例程简单介绍一GridSearchCV的使用,并展示如何使用自定义验证集进行模型调参。
首先解释一下什么叫使用自定义验证集进行模型调参。GridSearchCV默认使用的模型验证方法是KFold交叉验证,但很多时候我们自己已经预先分配好了验证集,我们就要在这个验证集上评价模型好坏(有些任性),所以我们并不需要GridSearchCV为我们自动产生验证集,这就是所谓的使用自定义验证集进行模型调参。好了,我们首先简单认识一下GridSearchCV的使用。

1. 问题背景

现在假设我有一个训练集,特征为数组train_features,标签为数组train_labels。我还有一个测试集,特征为数组test_features,没有标签。我希望在训练集上学习一个线性SVM,来预测测试集标签。我们知道,SVM有一些超参数需要人工设置,对于线性SVM,最关键的应该就是惩罚参数C。如何找到最优的C呢?通常情况下,我们使用KFold交叉验证。下面就简单介绍一下。

2. GridSearchCV使用简介

直接上代码:

import numpy as np
from sklearn.grid_search import GridSearchCV
from sklearn.svm import LinearSVC
from sklearn.externals import joblib

train_features = np.load('train_features.npy')
train_labels = np.load('train_labels.npy')
test_features = np.load('test_features.npy')

clf = LinearSVC(random_state=0)
params_search = {'C':[1,10,100,1000]}               # 我们想要优化的参数
grid_search_params = {'estimator': clf,             # 目标分类器
                      'param_grid': params_search,  # 前面定义的我们想要优化的参数
                      'cv': 3,                      # 交叉验证split策略
                      'n_jobs': -1,                 # 并行运行的任务数,-1表示使用所有CPU
                      'verbose': 32}                # 输出信息,数字越大输出信息越多
grsearch = GridSearchCV(**grid_search_params)
grsearch.fit(train_features, train_labels)
joblib.dump(grsearch, 'grsearch.model')

bst = grsearch.best_estimator_
preds = bst.predict(test_features)

在上面的代码中,我们使用3-fold交叉验证策略需找C的最优取值,每次的验证集从总的训练集中随机产生。

3. 使用自定义验证集

现在假设我们已经通过某种方式自己定义了训练集和验证集的划分方式,分别为train_featuresval_features,我们并不想使用随机的划分,这时候要怎么办呢?可以使用PredefinedSplit

import numpy as np
from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import PredefinedSplit
from sklearn.svm import LinearSVC
from sklearn.externals import joblib

train_features = np.load('train_features.npy')
train_labels = np.load('train_labels.npy')
val_features = np.load('val_features.npy')
val_labels = np.load('val_labels.npy')
test_features = np.load('test_features.npy')

# 合并训练集和验证集
train_val_features = np.concatenate((train_features,val_features ),axis=0)
train_val_labels = np.concatenate((train_labels,val_labels ),axis=0)

clf = LinearSVC(random_state=0)
test_fold = np.zeros(train_val_features.shape[0])   # 将所有index初始化为0,0表示第一轮的验证集
test_fold[:train_features.shape[0]] = -1            # 将训练集对应的index设为-1,表示永远不划分到验证集中
ps = PredefinedSplit(test_fold=test_fold)
params_search = {'C':[1,10,100,1000]}
grid_search_params = {'estimator': clf,             # 目标分类器
                      'param_grid': params_search,  # 前面定义的我们想要优化的参数
                      'cv': ps,                     # 使用前面自定义的split验证策略
                      'n_jobs': -1,                 # 并行运行的任务数,-1表示使用所有CPU
                      'verbose': 32}                # 输出信息,数字越大输出信息越多
print train_features.shape
print train_labels.shape
grsearch = GridSearchCV(**grid_search_params)
grsearch.fit(train_test_features, train_test_labels)

joblib.dump(grsearch, model_save_path)
bst = grsearch.best_estimator_
preds = bst.predict(test_features)

这里test_fold是一个索引list,用于划分数据集。除了上面使用的固定一个验证集,还可以划分多重验证集。加入数据集中有4个样本,那么test_fold = [0, 1, -1, 1]就表示在第一个验证集包含索引值为0的样本,第二个验证集包含引值为1的样本,以此类推,从而建立自定义的多重验证集。
这里有一段代码展示了这种划分方式:

>>> from sklearn.cross_validation import PredefinedSplit
>>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
>>> y = np.array([0, 0, 1, 1])
>>> ps = PredefinedSplit(test_fold=[0, 1, -1, 1])
>>> len(ps)
2
>>> print(ps)       
sklearn.cross_validation.PredefinedSplit(test_fold=[ 0  1 -1  1])
>>> for train_index, test_index in ps:
...    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]
TRAIN: [1 2 3] TEST: [0]
TRAIN: [0 2] TEST: [1 3]

相关链接

  1. http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV
  2. http://scikit-learn.org/stable/modules/generated/sklearn.grid_search.GridSearchCV.html
  3. http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.PredefinedSplit.html
  4. https://stackoverflow.com/questions/31948879/using-explict-predefined-validation-set-for-grid-search-with-sklearn
  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Python运行这些代码,你需要确保已经安装了相应的包。大多数包都可以使用`pip`进行安装。 首先,在命令行运行以下命令来安装所需的包: ```bash pip install scikit-learn pandas matplotlib numpy ``` 然后,在你的Python脚本导入所需的库: ```python from sklearn.model_selection import train_test_split from sklearn.decomposition import PCA import pandas as pd from sklearn import svm import numpy as np import math import matplotlib.pyplot as plt import matplotlib as mpl from matplotlib import colors from sklearn.model_selection import train_test_split from sklearn import datasets from matplotlib.colors import ListedColormap from sklearn.svm import SVC from sklearn.preprocessing import StandardScaler from sklearn.model_selection import StratifiedShuffleSplit, StratifiedKFold from sklearn.model_selection import GridSearchCV from sklearn.model_selection import GridSearchCV, LeaveOneOut, cross_val_predict from sklearn.model_selection import KFold from sklearn.linear_model import LogisticRegression from sklearn.naive_bayes import GaussianNB from sklearn.neighbors import KNeighborsClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import roc_auc_score import datetime import multiprocessing as mp from sklearn.ensemble import StackingClassifier from sklearn.pipeline import make_pipeline from sklearn.svm import LinearSVC import random ``` 请确保在运行这些代码之前,已经安装了所需的Python库。如果遇到任何问题,请确保已正确安装这些库,并且版本与代码兼容。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值