机器学习18-超参数搜索

网格搜索 (GridSearch) ( G r i d S e a r c h )

网格搜索是对多种超参数组合的空间进行暴力搜索。

class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=’raise’, return_train_score=’warn’)[source]

estimator:所使用的分类器。
param_grid:值为字典或者列表,即需要最优化的参数的取值,eg: param_grid = {‘n_estimators’:range(10,71,10)}。
scoring :准确度评价标准,默认None,这时需要使用score函数;或者如scoring=’roc_auc’,根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。
cv :交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练/测试数据的生成器。
refit :默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。
iid:默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。
verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。
n_jobs: 并行数,int:个数,-1:跟CPU核数一致, 1:默认值。
pre_dispatch:指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次
grid.fit():运行网格搜索
grid_scores_:给出不同参数情况下的评价结果
best_params_:描述了已取得最佳结果的参数的组合
best_score_:成员提供优化过程期间观察到的最好的评分

使用单线程对文本分类的朴素贝叶斯模型的超参数组合执行网格搜索

from sklearn.datasets import fetch_20newsgroups
import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline

news = fetch_20newsgroups(subset='all')
X_train, X_test, y_train, y_test = train_test_split(news.data[: 3000], news.target[: 3000], test_size=0.25, random_state=33)
clf = Pipeline([('vect', TfidfVectorizer(stop_words='english', analyzer='word')), ('svc', SVC())])

#这里需要试验的2个超参数的个数分别是4、3, svc__gamma的参数共有10^-2, 10^-1...。
#这样我们一共有12种的超参数组合,12个不同参数下的模型
# SVM模型有两个非常重要的参数C与gamma。
# 其中 C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。
# C越小,容易欠拟合。C过大或过小,泛化能力变差
# gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_features
parameters = {'svc__gamma': np.logspace(-2, 1, 4), 'svc__C': np.logspace(-1, 1, 3)}
#3折交叉验证,并输出所有子模型,
gs = GridSearchCV(clf, parameters, verbose=2, refit=True, cv=3)

#执行单线程网格搜索
gs.fit(X_train, y_train)
print(gs.best_params_, gs.best_score_)
#输出最佳模型在测试集上的准确性
print(gs.score(X_test, y_test))
#out[]:
#......
# [CV] svc__C=10.0, svc__gamma=10.0 ....................................
# [CV] ..................... svc__C=10.0, svc__gamma=10.0, total=   6.6s
# [Parallel(n_jobs=1)]: Done  36 out of  36 | elapsed:  5.7min finished
# {'svc__C': 10.0, 'svc__gamma': 0.1} 0.7906666666666666
#0.8226666666666667

代码的输出说明:使用单线程的网格搜索技术对支持向量机模型在文本分类任务中的超参数组合进行调优,共有12组超参数 × × 3折交叉验证=36项独立运行的计算任务。该过程一共进行了5.7min,寻找到的最佳超参数组合在测试集上所能达成的最高分类准确性为82.27%。

尽管采用网格搜索结合交叉验证的方法,来寻找更好超参数组合的过程非常耗时;然而,一旦获取比较好的超参数组合,则可以保持一段时间使用。因此这是值得推荐并且相对一劳永逸的性能提升方法。更可喜的是,由于各个新模型在执行交叉验证的过程中间是相互独立的,所以我们可以充分利用多核处理器(Multicore processor)甚至是分布式的计算机资源来从事并行搜索(Parallel Grid Search),这样能够成倍地节省运算时间。

初始化配置并行网格搜索,n_jobs=-1代表使用该计算机全部的cpu。
gs = GridSearchCV(clf, parameters, verbose=2, refit=True, cv=3, n_jobs=-1)

from sklearn.datasets import fetch_20newsgroups
import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline

if __name__ == '__main__':

    news = fetch_20newsgroups(subset='all')
    X_train, X_test, y_train, y_test = train_test_split(news.data[: 3000], news.target[: 3000], test_size=0.25, random_state=33)
    clf = Pipeline([('vect', TfidfVectorizer(stop_words='english', analyzer='word')), ('svc', SVC())])

    #这里需要试验的2个超参数的个数分别是4、3, svc__gamma的参数共有10^-2, 10^-1...。
    #这样我们一共有12种的超参数组合,12个不同参数下的模型
    # SVM模型有两个非常重要的参数C与gamma。
    # 其中 C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。
    # C越小,容易欠拟合。C过大或过小,泛化能力变差
    # gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_features
    parameters = {'svc__gamma': np.logspace(-2, 1, 4), 'svc__C': np.logspace(-1, 1, 3)}
    #3折交叉验证,并输出所有子模型
    #初始化配置并行网格搜索,n_jobs=-1代表使用该计算机全部的cpu.
    gs = GridSearchCV(clf, parameters, verbose=2, refit=True, cv=3, n_jobs=-1)

    # 执行多线程并行网格搜索
    gs.fit(X_train, y_train)
    print(gs.best_params_, gs.best_score_)
    #输出最佳模型在测试集上的准确性
    print(gs.score(X_test, y_test))

#out[]:
# [CV] ..................... svc__C=10.0, svc__gamma=10.0, total=   8.9s
# [CV] ..................... svc__C=10.0, svc__gamma=10.0, total=   9.1s
# [CV] ..................... svc__C=10.0, svc__gamma=10.0, total=   9.1s
# [Parallel(n_jobs=-1)]: Done  36 out of  36 | elapsed:  2.0min finished
# {'svc__C': 10.0, 'svc__gamma': 0.1} 0.7906666666666666
#0.8226666666666667

使用多线程并行搜索技术进行调优,只花费了2.0min, 寻找到的最佳的超参数组合在测试集上所能达成的最高分类准确性依然为82.27%。
所以在不影响验证准确性的前提下,并行搜索节省了最佳超参数组合的搜索时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值