【火爐煉AI】機器學習017-使用GridSearch搜尋最佳引數組合
(本文所使用的Python庫和版本號: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
在前面的文章(【火爐煉AI】機器學習012-用隨機森林構建汽車評估模型及模型的優化提升方法),我們使用了驗證曲線來優化模型的超引數,但是使用驗證曲線難以同時優化多個引數的取值,只能一個引數一個引數的優化,從而獲取每個引數的最優值,但是有時候,一個非常優秀的模型,可能A引數取最優值時,B引數並不一定是最優值,從而使得驗證曲線的方式有其自身的弊端。
此處介紹的使用GridSearch來搜尋最佳引數組合的方法,可以避免上述弊端,GridSearch可以同時優化多個不同引數的取值。
1. 準備資料集
資料集的準備工作和文章(【火爐煉AI】機器學習014-用SVM構建非線性分類模型)中一模一樣,此處不再贅述。
2. 使用GridSearch函式來尋找最優引數
使用GridSearch函式來尋找最優引數,需要首先定義要搜尋的引數候選值,然後定義模型的評價指標,以此來評價模型的優虐。,GridSearch會自動計算各種引數候選值,從而得到最佳的引數組合,使得評價指標最大化。
from sklearn import svm, grid_search, cross_validation
from sklearn.metrics import classification_report
parameter_grid = [ {'kernel': ['linear'], 'C': [1, 10, 50, 600]}, # 需要優化的引數及其候選值
{'kernel': ['poly'], 'degree': [2, 3]},
{'kernel': ['rbf'], 'gamma': [0.01, 0.001], 'C': [1, 10, 50, 600]},
]
metrics = ['precision', 'recall_weighted'] # 評價指標好壞的標準
for metric in metrics:
print("Searching optimal hyperparameters for: {}".format(metric))
classifier = grid_search.GridSearchCV(svm.SVC(C=1),
parameter_grid, cv=5, scoring=metric)
classifier.fit(train_X, train_y)
print("\nScores across the parameter grid:")
for params, avg_score, _ in classifier.grid_scores_: # 列印出該引數下的模型得分
print('{}: avg_scores: {}'.format(params,round(avg_score,3)))
print("\nHighest scoring parameter set: {}".format(classifier.best_params_))
y_pred =classifier.predict(test_X) # 此處自動呼叫最佳引數??
print("\nFull performance report:\n {}".format(classification_report(test_y,y_pred)))
複製程式碼
---------------------------輸---------出--------------------------------
Searching optimal hyperparameters for: precision
Scores across the parameter grid:
{'C': 1, 'kernel': 'linear'}: avg_scores: 0.809
{'C': 10, 'kernel': 'linear'}: avg_scores: 0.809
{'C': 50, 'kernel': 'linear'}: avg_scores: 0.809
{'C': 600, 'kernel': 'linear'}: avg_scores: 0.809
{'degree': 2, 'kernel': 'poly'}: avg_scores: 0.859
{'degree': 3, 'kernel': 'poly'}: avg_scores: 0.852
{'C': 1, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 1.0
{'C': 1, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.0
{'C': 10, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 0.968
{'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.855
{'C': 50, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 0.946
{'C': 50, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.975
{'C': 600, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 0.948
{'C': 600, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.968
Highest scoring parameter set: {'C': 1, 'gamma': 0.01, 'kernel': 'rbf'}
Full performance report:
---- | precision | recall | f1-score | support |
---|---|---|---|---|
0 | 0.75 | 1.00 | 0.86 | 36 |
1 | 1.00 | 0.69 | 0.82 | 39 |
avg / total | 0.88 | 0.84 | 0.84 | 75 |
Searching optimal hyperparameters for: recall_weighted
Scores across the parameter grid:
{'C': 1, 'kernel': 'linear'}: avg_scores: 0.653
{'C': 10, 'kernel': 'linear'}: avg_scores: 0.653
{'C': 50, 'kernel': 'linear'}: avg_scores: 0.653
{'C': 600, 'kernel': 'linear'}: avg_scores: 0.653
{'degree': 2, 'kernel': 'poly'}: avg_scores: 0.889
{'degree': 3, 'kernel': 'poly'}: avg_scores: 0.884
{'C': 1, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 0.76
{'C': 1, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.507
{'C': 10, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 0.907
{'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.658
{'C': 50, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 0.92
{'C': 50, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.72
{'C': 600, 'gamma': 0.01, 'kernel': 'rbf'}: avg_scores: 0.933
{'C': 600, 'gamma': 0.001, 'kernel': 'rbf'}: avg_scores: 0.902
Highest scoring parameter set: {'C': 600, 'gamma': 0.01, 'kernel': 'rbf'}
Full performance report:
---- | precision | recall | f1-score | support |
---|---|---|---|---|
0 | 1.00 | 0.92 | 0.96 | 36 |
1 | 0.93 | 1.00 | 0.96 | 39 |
avg / total | 0.96 | 0.96 | 0.96 | 75 |
--------------------------------完-------------------------------------
##################小**********結###############################
1. 使用GridSearch中的GridSearchCV可以實現最佳引數組合的搜尋,但需要指定候選引數和模型的評價指標。
2. 使用classifier.best_params_函式可以直接把最佳的引數組合列印出來,方便以後引數的直接呼叫
3. classifier.predict函式是自動呼叫最佳的引數組合來預測,從而得到該模型在測試集或訓練集上的預測值。
##########################################################
如果要使用最佳引數來構建SVM模型,可以採用下面的程式碼來實現:
best_classifier=svm.SVC(C=600,gamma=0.01,kernel='rbf') # 上面的full performance report的確使用的是最佳引數組合
best_classifier.fit(train_X, train_y)
y_pred =best_classifier.predict(test_X)
print("\nFull performance report:\n {}".format(classification_report(test_y,y_pred)))
複製程式碼
得到的結果和上面full performance report一模一樣。
注:本部分程式碼已經全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯