2016-03-08 228 views
12

我正在嘗試使用sklearn來評估多個機器學習算法,包括幾個指標(準確度,召回率,精度和可能更多)。在sklearn上評估多個分數cross_val_score

對於我從文檔here和源代碼中瞭解到的內容(我使用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 

這是好的,但對我自己的數據來說很慢。我如何測量所有分數?

+0

我會嘗試實現什麼'cross_val_score'正在做的手動 – Ryan

+0

使用Python 3。6此示例不起作用,因爲目標數據是多類的,但cross_val_score的平均值設置爲「二進制」。 您會收到以下錯誤消息:「ValueError:Target is multiclass but average ='binary'。Please choose another average setting。」 我該如何解決這個問題?不能真正將它二進制化,我可以嗎? –

+0

我用Python 2.7。和sklearn 0.17。我認爲這個錯誤發生在0.18。你使用什麼sklearn版本? –

回答

14

因爲寫這篇文章scikit學習已經更新,使我的答案過時的時候,看到下面


的更清潔的解決方案,您可以編寫自己的評分功能來捕獲所有三塊的信息,但交叉驗證的評分函數只能返回 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學習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.  ] 
10

我跑過同樣的問題,我創建了一個模塊,可以在cross_val_score中支持多個指標。
爲了完成你想要使用此模塊是什麼,你可以寫:

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' 

您可以檢查和GitHub下載該模塊。 希望它有幫助。