В чем разница между cross val score с scoring='roc auc' и ROC AUC score?
Я смущен разницей между метрикой скоринга cross_val_score "roc_auc" и roc_auc_score, которую я могу просто импортировать и вызывать напрямую.
документация (http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter) указывает, что указание scoring= 'roc_auc' будет использовать sklearn.метрика.roc_auc_score. Однако, когда я реализую GridSearchCV или cross_val_score со scoring= 'roc_auc', я получаю очень разные числа это когда я вызываю 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 ответов
это потому, что вы указали предсказанные y вместо вероятности в roc_auc_score. Эта функция принимает оценку, а не классифицированную метку. Попробуйте вместо этого сделать следующее:
print roc_auc_score(y_test, rf.predict_proba(X_test)[:,1])
Он должен дать аналогичный результат предыдущему результату из cross_val_score. см. этот пост для получения дополнительной информации.
Я только что столкнулся с подобной проблемой здесь. Ключевым вынос там было то, что 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')
столкнулся с этой проблемой сам, и после покопавшись немного нашел ответ. Делиться ради любви.
на самом деле есть две с половиной проблемы.
- вам нужно использовать тот же Kfold для сравнения баллов (тот же раскол поезда / теста);
- вам нужно кормить вероятности в
roc_auc_score
(черезpredict_proba()
метод). Но некоторые оценки (например, SVC) не имеютpredict_proba()
метод, затем вы используетеdecision_function()
метод.
вот полный пример:
# 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()
метод. Итак, согласно этому пример, мы делаем это:
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)