【问题标题】:Scikit: calculate precision and recall using cross_val_score functionScikit:使用 cross_val_score 函数计算精度和召回率
【发布时间】:2015-02-06 01:22:05
【问题描述】:

我正在使用 scikit 对垃圾邮件/火腿数据执行逻辑回归。 X_train 是我的训练数据,y_train 是标签('spam' 或 'ham'),我用这种方式训练了我的 LogisticRegression:

classifier = LogisticRegression()
classifier.fit(X_train, y_train)

如果我想获得 10 倍交叉验证的准确度,我只写:

 accuracy = cross_val_score(classifier, X_train, y_train, cv=10)

我认为可以通过简单地添加一个参数来计算精度和召回率:

precision = cross_val_score(classifier, X_train, y_train, cv=10, scoring='precision')
recall = cross_val_score(classifier, X_train, y_train, cv=10, scoring='recall')

但它会导致ValueError

ValueError: pos_label=1 is not a valid label: array(['ham', 'spam'], dtype='|S4') 

它与数据有关(我应该对标签进行二值化吗?)还是它们改变了cross_val_score 函数?

提前谢谢你!

【问题讨论】:

    标签: python machine-learning scikit-learn precision logistic-regression


    【解决方案1】:

    您上面显示的语法是正确的。您使用的数据似乎有问题。标签不需要二值化,只要它们不是连续数字即可。

    您可以用不同的数据集证明相同的语法:

    iris = sklearn.dataset.load_iris()
    X_train = iris['data']
    y_train = iris['target']
    
    classifier = LogisticRegression()
    classifier.fit(X_train, y_train)
    
    print cross_val_score(classifier, X_train, y_train, cv=10, scoring='precision')
    print cross_val_score(classifier, X_train, y_train, cv=10, scoring='recall')
    

    【讨论】:

      【解决方案2】:

      要计算召回率和准确率,数据确实必须进行二值化,这样:

      from sklearn import preprocessing
      lb = preprocessing.LabelBinarizer()
      lb.fit(y_train)
      

      更进一步,令我惊讶的是,当我想计算准确性时,我不必对数据进行二值化:

      accuracy = cross_val_score(classifier, X_train, y_train, cv=10)
      

      这只是因为准确度公式并不真正需要关于哪个类别被认为是正面或负面的信息:(TP + TN) / (TP + TN + FN + FP)。我们确实可以看到TP和TN是可以互换的,recall、precision和f1不是这样的。

      【讨论】:

        【解决方案3】:

        我在这里遇到了同样的问题,我解决了它

        # precision, recall and F1
        from sklearn.preprocessing import LabelBinarizer
        
        lb = LabelBinarizer()
        y_train = np.array([number[0] for number in lb.fit_transform(y_train)])
        
        recall = cross_val_score(classifier, X_train, y_train, cv=5, scoring='recall')
        print('Recall', np.mean(recall), recall)
        precision = cross_val_score(classifier, X_train, y_train, cv=5, scoring='precision')
        print('Precision', np.mean(precision), precision)
        f1 = cross_val_score(classifier, X_train, y_train, cv=5, scoring='f1')
        print('F1', np.mean(f1), f1)
        

        【讨论】:

          【解决方案4】:

          您可以使用这样的交叉验证来获得 f1-score 和召回:

          print('10-fold cross validation:\n')
          start_time = time()
          scores = cross_validation.cross_val_score(clf, X,y, cv=10, scoring ='f1')
          recall_score=cross_validation.cross_val_score(clf, X,y, cv=10, scoring ='recall')
          print(label+" f1: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), 'DecisionTreeClassifier'))
          print("---Classifier %s use %s seconds ---" %('DecisionTreeClassifier', (time() - start_time)))
          

          更多评分参数见the page

          【讨论】:

            【解决方案5】:

            你应该指定两个标签中哪个是正的(可能是火腿):

            from sklearn.metrics import make_scorer, precision_score
            
            precision = make_scorer(precision_score, pos_label="ham")
            
            accuracy = cross_val_score(classifier, X_train, y_train, cv=10, scoring = precision)
            

            【讨论】:

              猜你喜欢
              • 2012-11-26
              • 2017-06-21
              • 2014-11-20
              • 1970-01-01
              • 2015-12-05
              • 1970-01-01
              • 2019-12-14
              • 2016-07-26
              • 2020-02-23
              相关资源
              最近更新 更多