cross_val_score与得分=' roc_auc'之间有什么区别?和roc_auc_score?

时间:2015-11-11 00:19:27

标签: python machine-learning scikit-learn random-forest cross-validation

我对cross_val_score评分指标与roc_auc'之间的差异感到困惑。以及我可以直接导入和调用的roc_auc_score。

文档(http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter)表示指定评分=' roc_auc'将使用sklearn.metrics.roc_auc_score。但是,当我使用得分=' roc_auc'来实现GridSearchCV或cross_val_score时当我直接调用roc_auc_score时,我收到的数字非常不同。

这是我的代码,以帮助演示我所看到的内容:

# score the model using cross_val_score

rf = RandomForestClassifier(n_estimators=150,
                            min_samples_leaf=4,
                            min_samples_split=3,
                            n_jobs=-1)

scores = cross_val_score(rf, X, y, cv=3, scoring='roc_auc')

print scores
array([ 0.9649023 ,  0.96242235,  0.9503313 ])

# do a train_test_split, fit the model, and score with roc_auc_score

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
rf.fit(X_train, y_train)

print roc_auc_score(y_test, rf.predict(X_test))
0.84634039111363313 # quite a bit different than the scores above!

我觉得我在这里错过了一些非常简单的事情 - 很可能是我如何实施/解释其中一个评分指标的错误。

有人能否解释两个评分指标之间存在差异的原因?

3 个答案:

答案 0 :(得分:8)

这是因为你提供了预测的y而不是roc_auc_score中的概率。此功能采用分数,而不是分类标签。请尝试改为:

print roc_auc_score(y_test, rf.predict_proba(X_test)[:,1])

它应该给出与cross_val_score的先前结果类似的结果。 Refer to this post for more info

答案 1 :(得分:2)

我刚遇到类似的问题here。关键的一点是cross_val_score使用KFold策略和默认参数来进行训练测试分裂,这意味着分成连续的块而不是混乱。另一方面,train_test_split进行了混乱分裂。

解决方案是明确拆分策略并指定混洗,如下所示:

shuffle = cross_validation.KFold(len(X), n_folds=3, shuffle=True)
scores = cross_val_score(rf, X, y, cv=shuffle, scoring='roc_auc')

答案 2 :(得分:1)

自己陷入这个问题,挖了一下就找到了答案。分享爱情。

实际上有两个半问题。

  1. 你需要使用相同的Kfold来比较分数(火车/测试的相同分割);
  2. 您需要将概率提供给roc_auc_score(使用predict_proba()方法)。但是,一些估算器(如SVC)没有predict_proba()方法,您可以使用decision_function()方法。
  3. 以下是一个完整的例子:

    # Let's use the Digit dataset
    digits = load_digits(n_class=4)
    X,y = digits.data, digits.target
    y[y==2] = 0 # Increase problem dificulty
    y[y==3] = 1 # even more
    

    使用两个估算器

    LR = LogisticRegression()
    SVM = LinearSVC()
    

    拆分火车/测试装置。但请将其保存到我们可以重复使用的变量中。

    fourfold = StratifiedKFold(n_splits=4, random_state=4)
    

    将其输入GridSearchCV并保存分数。请注意,我们正在通过fourfold

    gs = GridSearchCV(LR, param_grid={}, cv=fourfold, scoring='roc_auc', return_train_score=True)
    gs.fit(X,y)
    gs_scores = np.array([gs.cv_results_[k][0] for k in gskeys])
    

    将其输入cross_val_score并保存分数。

     cv_scores = cross_val_score(LR, X, y, cv=fourfold, scoring='roc_auc')
    

    有时候,你想循环并计算几个不同的分数,所以这就是你使用的。

    loop_scores = list()
    for idx_train, idx_test in fourfold.split(X, y):
      X_train, y_train, X_test, y_test = X[idx_train], y[idx_train], X[idx_test], y[idx_test]
      LR.fit(X_train, y_train)
      y_prob = LR.predict_proba(X_test)
      auc = roc_auc_score(y_test, y_prob[:,1])
      loop_scores.append(auc)
    

    我们是否全面拥有相同的分数?

    print [((a==b) and (b==c)) for a,b,c in zip(gs_scores,cv_scores,loop_scores)]
    >>> [True, True, True, True]
    

    <小时/> 但是,有时我们的估算器没有predict_proba()方法。所以,根据这个example,我们这样做:

    for idx_train, idx_test in fourfold.split(X, y):
      X_train, y_train, X_test, y_test = X[idx_train], y[idx_train], X[idx_test], y[idx_test]
      SVM.fit(X_train, y_train)
      y_prob = SVM.decision_function(X_test)
      prob_pos = (y_prob - y_prob.min()) / (y_prob.max() - y_prob.min())
      auc = roc_auc_score(y_test, prob_pos)