做者|Michael Chau
编译|VK
来源|Towards Data Sciencehtml
你们都知道Scikit-Learn——它是数据科学家基本都知道的产品,提供了几十种易于使用的机器学习算法。它还提供了两种现成的技术来解决超参数调整问题:网格搜索(GridSearchCV)和随机搜索(RandomizedSearchCV)。python
这两种技术都是找到正确的超参数配置的强力方法,可是这是一个昂贵和耗时的过程!git
在这篇博客文章中,咱们介绍了tune-sklearn(https://github.com/ray-projec...,它使得在使用Scikit-Learn API的同时更容易利用这些新算法。github
Tune sklearn是Scikit Learn模型选择模块的一个替代品,采用了先进的超参数调整技术(贝叶斯优化、早期中止、分布式执行)——这些技术比网格搜索和随机搜索提供了显著的加速!算法
如下是tune sklearn提供的功能:api
Tune sklearn也很快。为了看到这一点,咱们在标准的超参数扫描上,将tune sklearn(启用早期中止)与本机Scikit Learn进行基准测试。在咱们的基准测试中,咱们能够看到普通笔记本电脑和48个CPU核心的大型工做站的显著性能差别。框架
对于更大的基准48核计算机,Scikit Learn花了20分钟在大小为40000的数据集上搜索75个超参数集。Tune sklearn只花了3.5分钟,而且以最小影响性能的方式执行。dom
第一个图:在我的双核i5 8gb ram笔记本电脑上,搜索6个超参集。第二个图:在一台48核250gb ram的大型计算机上,搜索75个超参集。机器学习
注意:对于较小的数据集(10000个或更少的数据点),在试图应用早期中止时,可能会牺牲准确性。咱们预计这不会对用户产生影响,由于该库旨在用大型数据集加速大型训练任务。分布式
运行pip install tune-sklearn ray[tune]
开始下面章节的示例代码。
让咱们来看看它是如何工做的。
Hyperparam set 2是一组没有但愿的超参数,它将被tune的早期中止机制检测到,并提早中止以免浪费训练时间和资源。
首先,只需更改import语句便可得到Tune的网格搜索交叉:
# from sklearn.model_selection import GridSearchCV from tune_sklearn import TuneGridSearchCV
从这里开始,咱们将像在Scikit Learn的接口风格中继续!让咱们使用一个“虚拟”自定义分类数据集和一个SGD分类程序来对数据进行分类。
咱们选择SGDClassifier是由于它有一个partial_fit的 API,这使得它可以中止拟合特定超参数配置的数据。若是估计器不支持早期中止,咱们将回到并行网格搜索。
# 导入其余库 import numpy as np from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.linear_model import SGDClassifier # 设置训练集和验证集 X, y = make_classification(n_samples=11000, n_features=1000, n_informative=50, n_redundant=0, n_classes=10, class_sep=2.5) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1000) # 从SGDClassifier调优的示例参数 parameters = { 'alpha': [1e-4, 1e-1, 1], 'epsilon':[0.01, 0.1] }
如你所见,这里的设置正是你为Scikit Learn所作的设置!如今,让咱们试着拟合一个模型。
tune_search = TuneGridSearchCV( SGDClassifier(), parameters, early_stopping=True, max_iters=10 ) import time # 比较拟合时间 start = time.time() tune_search.fit(X_train, y_train) end = time.time() print("Tune Fit Time:", end - start) pred = tune_search.predict(X_test) accuracy = np.count_nonzero(np.array(pred) == np.array(y_test)) / len(pred) print("Tune Accuracy:", accuracy)
请注意咱们在上面介绍的细微差异:
early_stopping决定什么时候中止,MedianStoppingRule 是一个很好的默认设置,可是请参阅Tune的关于调度器的文档,以得到可供选择的完整列表:https://docs.ray.io/en/master...
max_iters是给定的超参数集能够运行的最大迭代次数;若是提早中止搜索超参数集,则能够运行较少的迭代。
请尝试将其与GridSearchCV进行比较
from sklearn.model_selection import GridSearchCV # n_jobs=-1 使用全部内核 sklearn_search = GridSearchCV( SGDClassifier(), parameters, n_jobs=-1 ) start = time.time() sklearn_search.fit(X_train, y_train) end = time.time() print("Sklearn Fit Time:", end - start) pred = sklearn_search.predict(X_test) accuracy = np.count_nonzero(np.array(pred) == np.array(y_test)) / len(pred) print("Sklearn Accuracy:", accuracy)
除了网格搜索接口以外,tunesklearn还提供了一个接口TuneSearchCV,用于从超参数分布中进行采样。
此外,只需几行代码更改,就能够轻松地对TuneSearchCV中的发行版启用贝叶斯优化。
运行pip install scikit-optimize以尝试如下示例:
from tune_sklearn import TuneSearchCV # 其余导入 import scipy from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.linear_model import SGDClassifier # 设置训练集和验证集 X, y = make_classification(n_samples=11000, n_features=1000, n_informative=50, n_redundant=0, n_classes=10, class_sep=2.5) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1000) # 从SGDClassifier调优的示例参数 # 注意,若是须要贝叶斯优化,则使用元组 param_dists = { 'alpha': (1e-4, 1e-1), 'epsilon': (1e-2, 1e-1) } tune_search = TuneSearchCV(SGDClassifier(), param_distributions=param_dists, n_iter=2, early_stopping=True, max_iters=10, search_optimization="bayesian" ) tune_search.fit(X_train, y_train) print(tune_search.best_params_)
第1七、18和26行是为启用贝叶斯优化而更改的代码行
如你所见,将tunesklearn集成到现有代码中很是简单。你能够看看更详细的例子:https://github.com/ray-projec...。
另外请看一看Ray对joblib的替代,它容许用户在多个节点(而不只仅是一个节点)上并行化训练,从而进一步加快了训练速度。
注意:从导入ray.tune如连接文档所示,仅在nightly Ray wheels上可用,不久将在pip上提供
原文连接:https://towardsdatascience.co...
欢迎关注磐创AI博客站:
http://panchuang.net/
sklearn机器学习中文官方文档:
http://sklearn123.com/
欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/