0%

Scikit-learn Grid Search

在机器学习模型中,需要人工选择的参数称为超参数。比如SVM的Ckernelgamma,随机森林的n_estimators,人工神经网络模型中的隐藏层层数和每层的节点个数等等

对于各个分类器,各个参数及其对应值都通过get_params()获取

最常用的方法就是网格搜索(grid search),从而获得最佳的cross-validation的score,其中可分为: * GridSearchCV * RandomizedSearchCV

GridSearchCV

GridSearchCV,即带交叉验证的网格搜索,是一种常用的调参方法,其历遍param_grid中所有参数组成

param_grid = [{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4], 'C': [1, 10, 100, 1000]},
              {'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]

再将param_grid及models放入GridSearch中进行grid search

from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC

digits = datasets.load_digits()
n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1))
y = digits.target

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.5, random_state=0)

clf = GridSearchCV(SVC(), param_grid, cv=5)
clf.fit(X_train, y_train)

means = clf.cv_results_['mean_test_score']
stds = clf.cv_results_['std_test_score']
for mean, std, params in zip(means, stds, clf.cv_results_['params']):
    print("%0.3f (+/-%0.03f) for %r"% (mean, std * 2, params))
    
# 或者以DataFrame形式输出
import pandas as pd
results = pd.DataFrame(clf.cv_results_)
print(results.head())

对于结果的可视化,除了表格外,还可以有一些热图的形式(用不惯Python作图。。),进而从图形可视化中看看参数范围的选择是否合理!!!,比如:

import mglearn
scores = clf.cv_results_['mean_test_score'].reshape(3,4)
mglearn.tools.heatmap(scores, xlabel='C', xticklabels=param_grid[1]['C'], ylabel='rbf-linear', yticklabels=param_grid[0]['gamma'] + ['linear'])

GridSearchCV对分类问题默认使用分层K折交叉验证,对回归问题默认使用标准K折交叉验证,所以可以通过对于参数c的指定,进而选择不同的交叉验证方法,如ShuffleSplit等等

使用嵌套交叉验证(Nested cross-validation),可以进一步使用交叉验证进行多次划分,而不选择用train_test_split,这样可以避免结果的不稳定;调用cross_val_score即可实现,这样输出的结果则是N次交叉验证的结果

nested_score = cross_val_score(clf, X=iris.data, y=iris.target, cv=5)
print("Cross-validation scores: ", nested_score)

RandomizedSearchCV

RandomizedSearchCV也是一种调参方法,实现了对参数的随机搜索,在一定迭代次数下,从一个随机分布(或者人为指定参数,与GridSearchCV类似)中抽样选取算法参数;这样可以避免人为参数设定的局限性

分布可以从scipy.stats模块中挑选,比如expongammauniform等等,

对于连续的参数,比如 C,指定一个连续分布以便于充分利用随机化是很重要的,增加迭代次数将得到更好的结果。

使用方法跟上述GridSearchCV一样,先设置param_grid,然后调用RandomizedSearchCV,设置迭代次数n_iter,如:

param_dist = {"max_depth": [3, None],
              "max_features": sp_randint(1, 11),
              "min_samples_split": sp_randint(2, 11)}
random_search = RandomizedSearchCV(clf, param_distributions=param_dist, n_iter=20, cv=5, iid=False)

一些模型有其自带的参数拟合方法,其效果跟暴力参数搜索一样好,这个具体可看:https://scikit-learn.org/stable/modules/grid_search.html#alternatives-to-brute-force-parameter-search

参考资料:
Tuning the hyper-parameters of an estimator
《Python机器学习基础教程》

本文出自于http://www.bioinfo-scrounger.com转载请注明出处