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:
- Ejecutar múltiples veces
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. ]