基本使用
參數不沖突
參數不沖突時,直接用一個字典傳遞參數和要對應的候選值給GridSearchCV即可
我這里的參數沖突指的是類似下面這種情況:
① 參數取值受限:參數a='a'時,參數b只能取'b',參數a='A'時,參數b能取'b'或'B'
② 參數互斥:參數 a 或 b 二者只能選一個
from sklearn import datasets from sklearn.svm import SVC from sklearn.model_selection import GridSearchCV iris = datasets.load_iris() model = SVC(random_state=seed) # 需調參數及候選值 parameters = { 'C': [0.1, 1, 10], 'kernel': ['rbf', 'linear'] } # 評價依據 # https://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter scores = { 'acc': 'accuracy', # 准確率 'f1_mi': 'f1_micro', # 一種多分類f1值 } # 網格搜索實例 gs = GridSearchCV( model, parameters, cv=5, # 交叉驗證數 scoring=scores, # 評價指標 refit='f1_mi', # 在此指標下,用最優表現的參數重新訓練模型 # return_train_score=True, # gs.cv_results_額外保存訓練集的評價結果 verbose=1, # 日志信息,默認0不輸出 n_jobs=2 # 並行加速 ) # 一共要跑的任務數=參數1候選值*...*參數i候選值*交叉驗證數 # 這里就是3*2*5=30 gs.fit(iris.data, iris.target)
借助 make_scorer 可以自定義評價指標,如果指標越小越好,那么需要設置greater_is_better=False,sklearn會將這樣的指標取負,越小越好取負之后就等同於越大越好。
from sklearn.metrics import make_scorer def custom_loss_func(y_true, y_pred): return len(y_true[y_true!=y_pred])/len(y_true) # greater_is_better=False,指標越小越好 # needs_proba=False,指標通過標簽計算,不是通過概率 loss_socre = make_scorer(custom_loss_func, greater_is_better=False, needs_proba=False) scores = { 'acc': 'accuracy', # 准確率 'f1_mi': 'f1_micro', # 一種多分類f1值 'loss': loss_socre # 自定義評價指標 }
再通過 gs.best_params_ 獲取最優模型的參數,gs.best_estimator_取得最優模型(想這樣操作的話GridSearchCV的refit參數不能為False),
print("最優參數") print(gs.best_params_) print("最佳模型的評分") print(gs.best_score_) print("最優模型") best_model = gs.best_estimator_ # GridSearchCV的refit參數不能為False
gs.cv_results_ 存放了網格搜索的結果,如果想查看可以借助pandas,我們這里只列出了和評價指標有關的結果
""" 用表格查看訓練信息 """ cv_results = pd.DataFrame(gs.cv_results_) # 查看其他指標的結果和參數,比如這里按平均准確率排序 cv_results = cv_results.sort_values(by="mean_test_acc", ascending=False) shown_columns = ["mean_test_"+col for col in scores.keys()] + ["params"] cv_results[shown_columns].head(3)

參數沖突
參數沖突時,互斥參數搜索空間用不同字典來描述,然后將這些字典放到列表中,再傳遞給GridSearchCV
parameters = [ { 'C': [0.1, 1, 10], 'kernel': ['rbf', 'linear'] }, { 'C': [0.1, 1, 10], 'kernel': ['poly'], 'degree': [1, 3, 5] } ]
復合調參
管道可以用來連接多個操作,比如特征選擇+模型訓練,數據處理+模型訓練等等。如果這些操作也有參數可調,可以用 GridSearchCV 對它們一起調參
from sklearn import datasets from sklearn.pipeline import Pipeline from sklearn.feature_selection import SelectKBest, chi2, f_classif from sklearn.svm import SVC from sklearn.model_selection import GridSearchCV iris = datasets.load_iris() pipe = Pipeline([ ('selector', SelectKBest()), # 特征選擇 ('model', SVC(random_state=seed)) # 模型 ]) # “雙下划線”指定要調整的部件及其參數 parameters = [ { 'selector__score_func': [chi2, f_classif], 'selector__k': [2, 3, 4], 'model__C': [0.1, 1, 10], 'model__kernel': ['rbf', 'linear'] }, { 'selector__score_func': [chi2, f_classif], 'selector__k': [2, 3, 4], 'model__C': [0.1, 1, 10], 'model__kernel': ['poly'], 'model__degree': [1, 3, 5] } ] gs = GridSearchCV( pipe, parameters, cv=5, scoring='accuracy', verbose=1, n_jobs=2, ) gs.fit(iris.data, iris.target)
這時候獲得的 best_estimator_ 是管道,我們可以用索引獲取需要的組件(特征選擇器或模型)
print("最優組合") # best_pipe = gs.best_estimator_ best_selector = gs.best_estimator_[0] best_model = gs.best_estimator_[1]
