sklearn的GridSearchCV——網格搜索超參數調優


基本使用

參數不沖突

參數不沖突時,直接用一個字典傳遞參數和要對應的候選值給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]

 


免責聲明!

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



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