在sklearn cross_val_score上评估多个分数
machine-learning
python
scikit-learn
6
0

我正在尝试使用sklearn评估多个机器学习算法,以评估几个指标(准确性,召回率,精度,甚至更多)。

根据我从此处的文档和源代码(我正在使用sklearn 0.17)的理解cross_val_score函数每次执行仅接收一个计分器。因此,要计算多个分数,我必须:

  1. 多次执行
  2. 实施我的(耗时且容易出错的)计分器

    我已经用此代码执行了多次:

     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 

我得到以下输出:

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

可以,但是对于我自己的数据来说很慢。我如何衡量所有分数?

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

我遇到了同样的问题,并创建了一个模块,该模块可以支持cross_val_score多个指标。
为了完成此模块的工作,您可以编写:

from multiscorer import MultiScorer
import numpy as np
from sklearn.metrics import accuracy_score, precision_score, recall_score          
from sklearn.model_selection import cross_val_score
from numpy import average

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) # Added assignment of the result to `_` in order to illustrate that the return value will not be used
    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'

您可以从GitHub检查并下载此模块。希望能帮助到你。

收藏
评论

自撰写本文之时scikit-learn已更新,使我的答案过时了,请参阅下面的更简洁的解决方案


您可以编写自己的评分函数来捕获所有三条信息,但是用于交叉验证的评分函数只能在scikit-learn返回一个数字(这可能是出于兼容性原因)。下面是一个示例,其中每个交叉验证切片的每个分数都会打印到控制台,并且返回值只是这三个指标的总和。如果要返回所有这些值,则必须对cross_val_score (cross_validation.py的1351行)和_score (1601行或同一文件)进行一些更改。

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'

这使:

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 

从scikit-learn 0.19.0开始,解决方案变得更加容易

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

这使:

['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.        ]
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号