sklearn scikit model_selection learn gridsearchcv from for cross_validate cross_val_score accuracy accuracies python machine-learning scikit-learn

python - scikit - sklearn metrics for regression



Evaluar puntajes mĂșltiples en sklearn cross_val_score (2)

cross_val_score el mismo problema y creé un módulo que puede admitir múltiples métricas en cross_val_score .
Para lograr lo que desea con este módulo, puede escribir:

from multiscorer import MultiScorer import numpy as np scorer = MultiScorer({ ''Accuracy'' : (accuracy_score, {}), ''Precision'' : (precision_score, {''pos_label'': 3, ''average'':''macro''}), ''Recall'' : (recall_score, {''pos_label'': 3, ''average'':''macro''}) }) for model, name in zip(models, names): print name start = time.time() cross_val_score(model, iris.data, iris.target,scoring=scorer, cv=10) results = scorer.get_results() for metric_name in results.keys(): average_score = np.average(results[metric_name]) print(''%s : %f'' % (metric_name, average_score)) print ''time'', time.time() - start, ''/n/n''

Puede verificar y descargar este módulo desde GitHub . Espero eso ayude.

Estoy tratando de evaluar múltiples algoritmos de aprendizaje automático con sklearn para un par de métricas (precisión, recuperación, precisión y tal vez más).

Por lo que entendí de la documentación aquí y del código fuente (estoy usando sklearn 0.17), la función cross_val_score solo recibe un anotador por cada ejecución. Entonces, para calcular múltiples puntajes, tengo que:

  1. Ejecutar múltiples veces
  2. Implementar mi anotador (lento y propenso a errores)

    He ejecutado varias veces con este código:

    from sklearn.svm import SVC from sklearn.naive_bayes import GaussianNB from sklearn.tree import DecisionTreeClassifier from sklearn.cross_validation import cross_val_score import time from sklearn.datasets import load_iris iris = load_iris() models = [GaussianNB(), DecisionTreeClassifier(), SVC()] names = ["Naive Bayes", "Decision Tree", "SVM"] for model, name in zip(models, names): print name start = time.time() for score in ["accuracy", "precision", "recall"]: print score, print " : ", print cross_val_score(model, iris.data, iris.target,scoring=score, cv=10).mean() print time.time() - start

Y obtengo esta salida:

Naive Bayes accuracy : 0.953333333333 precision : 0.962698412698 recall : 0.953333333333 0.0383198261261 Decision Tree accuracy : 0.953333333333 precision : 0.958888888889 recall : 0.953333333333 0.0494720935822 SVM accuracy : 0.98 precision : 0.983333333333 recall : 0.98 0.063080072403

Lo cual está bien, pero es lento para mis propios datos. ¿Cómo puedo medir todos los puntajes?


Desde el momento de escribir esta publicación, scikit-learn se ha actualizado y ha dejado obsoleta mi respuesta; consulte la solución mucho más clara a continuación.

Puede escribir su propia función de puntuación para capturar las tres piezas de información, sin embargo, una función de puntuación para la validación cruzada solo debe devolver un solo número en scikit-learn (esto es probable por razones de compatibilidad). A continuación se muestra un ejemplo en el que cada una de las puntuaciones de cada segmento de validación cruzada se imprime en la consola, y el valor devuelto es solo la suma de las tres métricas. Si desea devolver todos estos valores, tendrá que realizar algunos cambios en cross_val_score (línea 1351 de cross_validation.py) y _score (línea 1601 o el mismo archivo).

from sklearn.svm import SVC from sklearn.naive_bayes import GaussianNB from sklearn.tree import DecisionTreeClassifier from sklearn.cross_validation import cross_val_score import time from sklearn.datasets import load_iris from sklearn.metrics import accuracy_score, precision_score, recall_score iris = load_iris() models = [GaussianNB(), DecisionTreeClassifier(), SVC()] names = ["Naive Bayes", "Decision Tree", "SVM"] def getScores(estimator, x, y): yPred = estimator.predict(x) return (accuracy_score(y, yPred), precision_score(y, yPred, pos_label=3, average=''macro''), recall_score(y, yPred, pos_label=3, average=''macro'')) def my_scorer(estimator, x, y): a, p, r = getScores(estimator, x, y) print a, p, r return a+p+r for model, name in zip(models, names): print name start = time.time() m = cross_val_score(model, iris.data, iris.target,scoring=my_scorer, cv=10).mean() print ''/nSum:'',m, ''/n/n'' print ''time'', time.time() - start, ''/n/n''

Lo que da:

Naive Bayes 0.933333333333 0.944444444444 0.933333333333 0.933333333333 0.944444444444 0.933333333333 1.0 1.0 1.0 0.933333333333 0.944444444444 0.933333333333 0.933333333333 0.944444444444 0.933333333333 0.933333333333 0.944444444444 0.933333333333 0.866666666667 0.904761904762 0.866666666667 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 Sum: 2.86936507937 time 0.0249638557434 Decision Tree 1.0 1.0 1.0 0.933333333333 0.944444444444 0.933333333333 1.0 1.0 1.0 0.933333333333 0.944444444444 0.933333333333 0.933333333333 0.944444444444 0.933333333333 0.866666666667 0.866666666667 0.866666666667 0.933333333333 0.944444444444 0.933333333333 0.933333333333 0.944444444444 0.933333333333 1.0 1.0 1.0 1.0 1.0 1.0 Sum: 2.86555555556 time 0.0237860679626 SVM 1.0 1.0 1.0 0.933333333333 0.944444444444 0.933333333333 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.933333333333 0.944444444444 0.933333333333 0.933333333333 0.944444444444 0.933333333333 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 Sum: 2.94333333333 time 0.043044090271

A partir de scikit-learn 0.19.0 la solución se vuelve mucho más fácil

from sklearn.model_selection import cross_validate from sklearn.datasets import load_iris from sklearn.svm import SVC iris = load_iris() clf = SVC() scoring = {''acc'': ''accuracy'', ''prec_macro'': ''precision_macro'', ''rec_micro'': ''recall_macro''} scores = cross_validate(clf, iris.data, iris.target, scoring=scoring, cv=5, return_train_score=True) print(scores.keys()) print(scores[''test_acc''])

Lo que da:

[''test_acc'', ''score_time'', ''train_acc'', ''fit_time'', ''test_rec_micro'', ''train_rec_micro'', ''train_prec_macro'', ''test_prec_macro''] [ 0.96666667 1. 0.96666667 0.96666667 1. ]