GridSearchCV de notation paramètre: à l'aide de la notation= " f1 " ou de la notation=None (par défaut utilise l'exactitude) donne le même résultat
Je suis à l'aide d'un exemple extrait du livre "la maîtrise de l'Apprentissage de la Machine avec scikit learn".
Il utilise un arbre de décision permettant de prédire si chacune des images sur une page web est un
de la publicité ou du contenu de l'article. Les Images qui sont classés comme étant des publicités pourraient alors être masqués à l'aide de Feuilles de Style en Cascade. Les données sont accessibles à partir de l'Internet Annonces Jeu de Données: http://archive.ics.uci.edu/ml/datasets/Internet+Annonces, qui contient des données pour 3,279 images.
Voici le code complet pour remplir la tâche de classification:
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV
import sys,random
def main(argv):
df = pd.read_csv('ad-dataset/ad.data', header=None)
explanatory_variable_columns = set(df.columns.values)
response_variable_column = df[len(df.columns.values)-1]
explanatory_variable_columns.remove(len(df.columns.values)-1)
y = [1 if e == 'ad.' else 0 for e in response_variable_column]
X = df[list(explanatory_variable_columns)]
X.replace(to_replace=' *\?', value=-1, regex=True, inplace=True)
X_train, X_test, y_train, y_test = train_test_split(X, y,random_state=100000)
pipeline = Pipeline([('clf',DecisionTreeClassifier(criterion='entropy',random_state=20000))])
parameters = {
'clf__max_depth': (150, 155, 160),
'clf__min_samples_split': (1, 2, 3),
'clf__min_samples_leaf': (1, 2, 3)
}
grid_search = GridSearchCV(pipeline, parameters, n_jobs=-1,verbose=1, scoring='f1')
grid_search.fit(X_train, y_train)
print 'Best score: %0.3f' % grid_search.best_score_
print 'Best parameters set:'
best_parameters = grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
print '\t%s: %r' % (param_name, best_parameters[param_name])
predictions = grid_search.predict(X_test)
print classification_report(y_test, predictions)
if __name__ == '__main__':
main(sys.argv[1:])
Les RÉSULTATS de l'utilisation scoring= " f1 " dans GridSearchCV comme dans l'exemple est:
Les RÉSULTATS de l'utilisation score=None (par défaut Précision de la mesure) est la même que l'utilisation de F1 score:
Si je ne me trompe pas l'optimisation du paramètre de recherche par les différentes fonctions de scoring devrait donner des résultats différents. Le cas suivant montre que des résultats différents sont obtenus lorsque score='précision' est utilisé.
Les RÉSULTATS de l'utilisation score='précision' est DIFFÉRENT que dans les deux autres cas. Il en serait de même pour le "rappel", etc:
POURQUOI 'F1' ET en leur absence, PAR DÉFAUT d'EXACTITUDE, de DONNER LE MÊME RÉSULTAT??
ÉDITÉ
Je suis d'accord avec les deux réponses par Fabian & Sebastian. Le problème devrait être la petite param_grid. Mais je voulais juste préciser que le problème a augmenté lorsque je travaillais avec un de totalement différent (pas celui dans l'exemple ici), très déséquilibre dataset 100:1 (ce qui devrait affecter la précision) et à l'aide de la Régression Logistique. Dans ce cas également " F1 " et de la précision a donné le même résultat.
La param_grid que j'ai utilisé, dans ce cas, était la suivante:
parameters = {"penalty": ("l1", "l2"),
"C": (0.001, 0.01, 0.1, 1, 10, 100),
"solver": ("newton-cg", "lbfgs", "liblinear"),
"class_weight":[{0:4}],
}
Je suppose que le paramètre de sélection est aussi trop petit.
Salut @NBartley, le scikit-learn version que j'utilise est 0.16.1
le montage d'un solveur comme un hyper-paramètre est plutôt redondant
OriginalL'auteur Pablo Fleurquin | 2015-10-01
Vous devez vous connecter pour publier un commentaire.
Je pense que l'auteur n'a pas choisi cet exemple très bien. J'ai peut-être raté quelque chose ici, mais
min_samples_split=1
ne fait pas de sens pour moi: N'est-il pas le même que le réglage demin_samples_split=2
puisque vous ne pouvez pas diviser 1 échantillon -- essentiellement, c'est une perte de temps de calcul.Btw. c'est une très petite grille et il n'y a pas beaucoup de choix, de toute façon, ce qui peut expliquer pourquoi
accuracy
etf1
vous donner les mêmes combinaisons de paramètres et donc les mêmes tableaux de pointage.Comme mentionné ci-dessus, l'ensemble de données peut être bien équilibré qui est pourquoi la F1 et de l'exactitude des scores peut préférer les mêmes combinaisons de paramètres. Donc, en regardant de plus à votre GridSearch résultats à l'aide de (a) F1 score et (b) l'Exactitude, la je en conclure que, dans les deux cas, une profondeur de 150 qui fonctionne le mieux. Puisque c'est la limite inférieure, il vous donne une légère hind que la baisse de la "profondeur" des valeurs peut fonctionner encore mieux. Cependant, je soupçonne que l'arbre n'a même pas d'aller en profondeur sur ce jeu de données (vous pouvez vous retrouver avec "pure" laisse même bien avant d'atteindre la profondeur max).
Donc, nous allons répéter l'expérience avec un peu plus raisonnable des valeurs en utilisant le paramètre suivant de la grille
Optimale "profondeur" pour le meilleur de la F1 score semble être autour de 15.
Ensuite, nous allons essayer, à l'aide de "l'exactitude" (ou
None
) que notre notation métrique:Comme vous pouvez le voir, vous obtenez des résultats différents, et les "optimale" de profondeur est différente si vous utilisez "l'exactitude."
OriginalL'auteur
Je ne suis pas d'accord que l'optimisation du paramètre de recherche par les différentes fonctions de scoring devraient aboutir nécessairement à des résultats différents nécessairement. Si votre jeu de données est équilibré (à peu près le même nombre d'échantillons dans chaque classe), je m'attends à ce que la sélection d'un modèle, l'exactitude et la F1 donnerait des résultats très similaires.
Aussi, avoir à l'esprit que GridSearchCV optimise sur une grille discrète. Peut-être l'aide d'un diluant grille de paramètres pour obtenir les résultats que vous recherchez.
OriginalL'auteur Fabian Pedregosa
Sur un déséquilibré dataset utiliser les "étiquettes" paramètre de la f1_score buteur pour utiliser uniquement la f1 score de la classe qui vous intéresse. Ou envisager d'utiliser "sample_weight".
OriginalL'auteur Diego