2016-05-11 28 views
8

Sto cercando un modo per tracciare griglia_scores_ da GridSearchCV in sklearn. In questo esempio sto provando a cercare nella griglia i migliori parametri gamma e C per un algoritmo SVR. Il mio codice è il seguente:Come graficare i punteggi della griglia da GridSearchCV?

C_range = 10.0 ** np.arange(-4, 4) 
    gamma_range = 10.0 ** np.arange(-4, 4) 
    param_grid = dict(gamma=gamma_range.tolist(), C=C_range.tolist()) 
    grid = GridSearchCV(SVR(kernel='rbf', gamma=0.1),param_grid, cv=5) 
    grid.fit(X_train,y_train) 
    print(grid.grid_scores_) 

Dopo aver eseguito il codice e stampare i punteggi della griglia ottengo il seguente esito:

[mean: -3.28593, std: 1.69134, params: {'gamma': 0.0001, 'C': 0.0001}, mean: -3.29370, std: 1.69346, params: {'gamma': 0.001, 'C': 0.0001}, mean: -3.28933, std: 1.69104, params: {'gamma': 0.01, 'C': 0.0001}, mean: -3.28925, std: 1.69106, params: {'gamma': 0.1, 'C': 0.0001}, mean: -3.28925, std: 1.69106, params: {'gamma': 1.0, 'C': 0.0001}, mean: -3.28925, std: 1.69106, params: {'gamma': 10.0, 'C': 0.0001},etc] 

vorrei visualizzare tutti i punteggi (valori medi) in funzione parametri gamma e C. Il grafico che sto cercando di ottenere dovrebbe essere come segue:

enter image description here

Dove asse x è gamma, asse y è medio punteggio (errore quadratico medio in questo caso), e diverse linee rappresentano differenti C valori.

risposta

7
from sklearn.svm import SVC 
from sklearn.grid_search import GridSearchCV 
from sklearn import datasets 
import matplotlib.pyplot as plt 
import seaborn as sns 
import numpy as np 

digits = datasets.load_digits() 
X = digits.data 
y = digits.target 

clf_ = SVC(kernel='rbf') 
Cs = [1, 10, 100, 1000] 
Gammas = [1e-3, 1e-4] 
clf = GridSearchCV(clf_, 
      dict(C=Cs, 
       gamma=Gammas), 
       cv=2, 
       pre_dispatch='1*n_jobs', 
       n_jobs=1) 

clf.fit(X, y) 

scores = [x[1] for x in clf.grid_scores_] 
scores = np.array(scores).reshape(len(Cs), len(Gammas)) 

for ind, i in enumerate(Cs): 
    plt.plot(Gammas, scores[ind], label='C: ' + str(i)) 
plt.legend() 
plt.xlabel('Gamma') 
plt.ylabel('Mean score') 
plt.show() 
  • Codice si basa su this.
  • Solo una parte sconcertante: si sklearn sempre rispettare l'ordine di C & Gamma -> esempio ufficiale usa questo "ordinamento"

uscita:

Example plot

2

L'ordine che la griglia di parametri è attraversato è deterministico, tale da poter essere rimodellato e tracciato direttamente. Qualcosa del genere:

scores = [entry.mean_validation_score for entry in grid.grid_scores_] 
# the shape is according to the alphabetical order of the parameters in the grid 
scores = np.array(scores).reshape(len(C_range), len(gamma_range)) 
for c_scores in scores: 
    plt.plot(gamma_range, c_scores, '-') 
+0

"# la forma è secondo l'ordine alfabetico dei parametri nella griglia" - Avete qualche link per questo (preferibilmente dai documenti)? – sascha

+0

Ho trovato la parte in codeb di sklearns all'interno di grid_search.py, ma penso che non sia menzionata nei documenti. – sascha

+0

Hai ragione, dovrebbe essere menzionato e non lo è. Il doctest per ParameterGrid garantisce l'ordine deterministico che segue questa convenzione, quindi è testato; è anche usato nell'esempio 'plot_rbf_parameters' che ha due linee coincidenti per coincidenza quasi identiche a quelle che ti ho dato. Se sei preoccupato che questo ordine sia inaffidabile, puoi sempre ordinare il file 'grid_scores_ '. – joeln

10

Il codice mostrato da @sascha è corretto. Tuttavia, l'attributo grid_scores_ sarà presto deprecato. È preferibile utilizzare l'attributo cv_results.

Può essere implemente in un modo simile a quello del metodo @sascha:

def plot_grid_search(cv_results, grid_param_1, grid_param_2, name_param_1, name_param_2): 
    # Get Test Scores Mean and std for each grid search 
    scores_mean = cv_results['mean_test_score'] 
    scores_mean = np.array(scores_mean).reshape(len(grid_param_2),len(grid_param_1)) 

    scores_sd = cv_results['std_test_score'] 
    scores_sd = np.array(scores_sd).reshape(len(grid_param_2),len(grid_param_1)) 

    # Plot Grid search scores 
    _, ax = plt.subplots(1,1) 

    # Param1 is the X-axis, Param 2 is represented as a different curve (color line) 
    for idx, val in enumerate(grid_param_2): 
     ax.plot(grid_param_1, scores_mean[idx,:], '-o', label= name_param_2 + ': ' + str(val)) 

    ax.set_title("Grid Search Scores", fontsize=20, fontweight='bold') 
    ax.set_xlabel(name_param_1, fontsize=16) 
    ax.set_ylabel('CV Average Score', fontsize=16) 
    ax.legend(loc="best", fontsize=15) 
    ax.grid('on') 

# Calling Method 
plot_grid_search(pipe_grid.cv_results_, n_estimators, max_features, 'N Estimators', 'Max Features') 

I risultati di cui sopra nel seguente grafico:

enter image description here

0

ho voluto fare qualcosa di simile (ma scalabile per un gran numero di parametri) e qui è la mia soluzione per generare sciami di output:

score = pd.DataFrame(gs_clf.grid_scores_).sort_values(by='mean_validation_score', ascending = False) 
for i in parameters.keys(): 
    print(i, len(parameters[i]), parameters[i]) 
score[i] = score.parameters.apply(lambda x: x[i]) 
l =['mean_validation_score'] + list(parameters.keys()) 
for i in list(parameters.keys()): 
    sns.swarmplot(data = score[l], x = i, y = 'mean_validation_score') 
    #plt.savefig('170705_sgd_optimisation//'+i+'.jpg', dpi = 100) 
    plt.show() 

SGDclassifier Loss Function Example