sklearn中的超參數調節


進行參數的選擇是一個重要的步驟。在機器學習當中需要我們手動輸入的參數叫做超參數,其余的參數需要依靠數據來進行訓練,不需要我們手動設定。進行超參數選擇的過程叫做調參。

進行調參應該有一下准備條件:

  • 一個學習器
  • 一個參數空間
  • 一個從參數空間當中尋找參數的方法
  • 一個交叉驗證的規則
  • 一個性能評估的策略

下面我介紹幾種調參的方法:

1:窮舉式的網格搜索

sklearn當中的GridSearchCV實現了這種窮舉是的網格搜索,其實這種方法是很簡單的。下面是使用交叉驗證來進行網格搜索的一個例子:

from sklearn import datasets
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.metrics import classification_report
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)
#上面的操作是導入數據,並且把數據划分為訓練數據和測試數據,這里使用的是手寫數字識別數據集

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

scores = ['precision', 'recall']   #這是我們使用的評分策略,因為是多分類問題,所以最后的評分策略為precision_macro 和 recall_macro 見下面

for score in scores:
    print("# Tuning hyper-parameters for %s" % score)
    print()

    clf = GridSearchCV(SVC(), tunned_parameters, cv=5,
                       scoring='%s_macro' % score)
    clf.fit(X_train, y_train)

    print("Best parameters set found on development set:")
    print()
    print(clf.best_params_)
    print()
    print("Grid scores on development set:")
    print()
    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))
    print()

    print("Detailed classification report:")
    print()
    print("The model is trained on the full development set.")
    print("The scores are computed on the full evaluation set.")
    print()
    #這里是使用訓練出來的最好的參數進行預測
    y_true, y_pred = y_test, clf.predict(X_test)
    print(classification_report(y_true, y_pred))
    print()

 

實際當中有用的參數,以clf表示我們的GridSearchCV對象

clf.best_params_   返回最好的參數

clf.best_score_  返回最好的測試分數,它的值和 clf.cv_results_['mean_test_score'][dt_grid.best_index_] 是相同的。

clf.best_index_  返回列表中分數最好的下表

clf.best_estimator_  返回最好的模型

grid_scores_     在sklearn 0.18中已經不贊成使用了,用下面的cv_results_來代替

clf.cv_results_     返回使用交叉驗證進行搜索的結果,它本身又是一個字典,里面又有很多內容,我們來看一下上面的clf.cv_results_.keys()里面有什么:

dict_keys(
['mean_fit_time', 'std_fit_time', 'mean_score_time', 'std_score_time', 
'param_C', 'param_gamma', 'param_kernel', 'params', 
'split0_test_score', 'split1_test_score', 'split2_test_score', 'split3_test_score', 'split4_test_score',
'mean_test_score', 'std_test_score', 'rank_test_score', 
'split0_train_score', 'split1_train_score', 'split2_train_score', 'split3_train_score', 'split4_train_score', 
'mean_train_score', 'std_train_score'] )

可以分為上面幾類: 第一類是時間, 第二類是參數, 第三類是測試分數,其中又分為每次交叉驗證的參數和統計的參數,第四類是訓練分數,其中也分為每次交叉驗證的參數和統計的參數。

 

2: 隨機搜索

隨機搜索就是制定參數的隨機分布的策略,從這些策略當中隨機產生我們需要的參數進行評估。sklearn當中使用RandomizedSearchCV來完成。

比如下面使用了scipy統計庫中的指數分布,其中scale參數制定隨機變量的縮放比例。然后RandomizedSearchCV會根據這些分布選取參數

{'C': scipy.stats.expon(scale=100), 'gamma': scipy.stats.expon(scale=.1),
  'kernel': ['rbf'], 'class_weight':['balanced', None]}

一個例子是這樣的:

import numpy as np

from time import time
from scipy.stats import randint as sp_randint

from sklearn.model_selection import RandomizedSearchCV
from sklearn.datasets import load_digits
from sklearn.ensemble import RandomForestClassifier

# get some data
digits = load_digits()
X, y = digits.data, digits.target

# build a classifier
clf = RandomForestClassifier(n_estimators=20)


# Utility function to report best scores
def report(results, n_top=3):
    '''
    這是自定義的打印函數,results為一個字典,里面包含訓練以后的結果,
    其中rank_test_score為參數排序的結果,下面的代碼是根據rank_test_score
    的值取出排名靠前的均值、方差和參數
    '''
    for i in range(1, n_top + 1):
        candidates = np.flatnonzero(results['rank_test_score'] == i)
        for candidate in candidates:
            print("Model with rank: {0}".format(i))
            print("Mean validation score: {0:.3f} (std: {1:.3f})".format(
                results['mean_test_score'][candidate],
                results['std_test_score'][candidate]))
            print("Parameters: {0}".format(results['params'][candidate]))
            print("")



# specify parameters and distributions to sample from
#這里使用了scipy統計庫中的randint分布函數
param_dist = {"max_depth": [3, None],
              "max_features": sp_randint(1, 11),
              "min_samples_split": sp_randint(2, 11),
              "min_samples_leaf": sp_randint(1, 11),
              "bootstrap": [True, False],
              "criterion": ["gini", "entropy"]}

# run randomized search
n_iter_search = 20
random_search = RandomizedSearchCV(clf, param_distributions=param_dist,
                                   n_iter=n_iter_search)

start = time()
random_search.fit(X, y)
print("RandomizedSearchCV took %.2f seconds for %d candidates"
      " parameter settings." % ((time() - start), n_iter_search))
report(random_search.cv_results_)

#源代碼后面還有一個GridSearchCV代碼,這里刪除了

輸出結果如下:

RandomizedSearchCV took 3.38 seconds for 20 candidates parameter settings.
Model with rank: 1
Mean validation score: 0.924 (std: 0.006)
Parameters: {'bootstrap': True, 'criterion': 'entropy', 'max_depth': None, 'max_features': 6, 'min_samples_leaf': 1, 'min_samples_split': 3}

Model with rank: 2
Mean validation score: 0.922 (std: 0.007)
Parameters: {'bootstrap': True, 'criterion': 'gini', 'max_depth': None, 'max_features': 7, 'min_samples_leaf': 1, 'min_samples_split': 9}

Model with rank: 3
Mean validation score: 0.918 (std: 0.015)
Parameters: {'bootstrap': False, 'criterion': 'entropy', 'max_depth': None, 'max_features': 9, 'min_samples_leaf': 7, 'min_samples_split': 7}

 

3:貝葉斯優化(Bayesian optimazation)

前兩種策略屬於那種參數的選擇的時候相互獨立的情況,這種情況並沒有完全利用好上一次選擇的參數所得到的一些信息。而貝葉斯優化則更好相反,這一類優化充分利用了前面所選擇的參數的信息,屬於sequential model-based optimization (SMBO)。

 

 

 

 

 

 

 

 

 

 

 

 

 

參考:

淺談高斯過程回歸

Hyper-parameter tuning for machine learning models

Tuning the hyper-parameters of an estimator


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM