2016-05-11 5 views
8

Ich bin auf der Suche nach einer Möglichkeit, GridScores aus GridSearchCV in Sklearn zu zeichnen. In diesem Beispiel versuche ich, nach den besten Gamma- und C-Parametern für einen SVR-Algorithmus zu suchen. Mein Code sieht wie folgt aus:Wie Graph Rasterpunkte von GridSearchCV grafisch darstellen?

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_) 

Nachdem ich den Code und drucken die Raster erzielt Run ich folgendes Ergebnis erhalten:

[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] 

Ich mag würde alle Werte sichtbar zu machen (Mittelwerte) in Abhängigkeit von Gamma- und C-Parameter. Der Graph ich versuche aussehen sollte wie folgt zu erhalten:

enter image description here

Wo x-Achse ist Gamma, y-Achse ist mittlere Punktzahl (root in diesem Fall quadratische Fehler bedeutet) und verschiedene Linien repräsentieren verschiedene C Werte.

Antwort

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() 
  • -Code wird auf this basiert.
  • Nur verwirrende Teil: wird sklearn immer die Reihenfolge der & Gamma C respektieren -> offizielle Beispiel verwendet diese "Ordnung"

Ausgang:

Example plot

2

Die Reihenfolge, in der Parameter Raster ist durchlaufen ist deterministisch, so dass es neu geformt und einfach gezeichnet werden kann. Etwas wie dieses:

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

"# Die Form entspricht der alphabetischen Reihenfolge der Parameter im Raster" - Haben Sie einen Link dafür (vorzugsweise aus der Dokumentation)? – sascha

+0

Ich fand den Teil in Sklearns Codebase innerhalb von grid_search.py, aber ich denke, dass es in den Dokumenten nicht erwähnt wird. – sascha

+0

Sie haben Recht, es sollte erwähnt werden und ist es nicht. Der doctest für ParameterGrid stellt eine deterministische Reihenfolge sicher, die dieser Konvention folgt, also getestet wurde; Es wird auch im 'plot_rbf_parameters'-Beispiel verwendet, das zufällig zwei Zeilen enthält, die zufällig fast identisch mit denen sind, die ich dir gegeben habe. Wenn Sie sich Sorgen machen, dass diese Reihenfolge unzuverlässig ist, können Sie die 'grid_scores_' immer selbst sortieren. – joeln

10

Der von @sascha angezeigte Code ist korrekt. Das Attribut grid_scores_ wird jedoch bald veraltet sein. Es ist besser, das Attribut cv_results zu verwenden.

Es kann in ähnlicher Weise wie bei @sascha Methode implemente werden:

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') 

Die obigen Ergebnisse in der folgenden Handlung:

enter image description here

0

ich etwas Ähnliches tun wollte (aber skalierbar auf eine große Anzahl von Parametern) und hier ist meine Lösung, um Schwarm-Plots der Ausgabe zu erzeugen:

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

Verwandte Themen