9

Tôi đang bối rối về sự khác biệt giữa chỉ số chấm điểm chéo__kết_thị 'roc_auc' và roc_auc_score mà tôi chỉ có thể nhập và gọi trực tiếp.Sự khác nhau giữa cross_val_score với điểm = 'roc_auc' và roc_auc_score là gì?

Tài liệu (http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter) cho biết rằng chỉ định điểm = 'roc_auc' sẽ sử dụng sklearn.metrics.roc_auc_score. Tuy nhiên, khi tôi thực hiện GridSearchCV hoặc cross_val_score với điểm = 'roc_auc' tôi nhận được các số rất khác nhau khi tôi gọi roc_auc_score trực tiếp.

Đây là mã của tôi để giúp chứng minh những gì tôi thấy:

# 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! 

tôi cảm thấy như tôi đang thiếu một cái gì đó rất đơn giản ở đây - có thể là một sai lầm trong cách Tôi đang thực hiện/giải thích một trong những số liệu ghi bàn .

Có ai có thể làm sáng tỏ lý do cho sự khác biệt giữa hai chỉ số tính điểm không?

+0

Tôi cũng hoàn toàn bối rối bởi sự khác biệt này. Tôi cũng đã thử sử dụng hàm make_scorer() tiêu chuẩn để biến một hàm điểm thành một đối tượng Người ghi bàn chính xác cho cross_val_score, nhưng kết quả là như nhau. make_scorer() cho kết quả tương tự như việc thực hiện thủ công của tôi, trong khi 'roc_auc' cho điểm cao hơn. May mắn thay sự khác biệt là vài% trong ví dụ của tôi, không giống như bạn, nhưng vẫn: tôi nên tin vào chức năng nào? –

Trả lời

6

Điều này là do bạn cung cấp dự đoán y là thay vì xác suất trong roc_auc_score. Hàm này lấy điểm, không phải nhãn được phân loại. Thay vào đó, hãy thử thực hiện việc này:

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

Kết quả tương tự với kết quả trước đó từ cross_val_score. Refer to this post for more info.

+1

Bạn hoàn toàn đúng! Tôi sẽ cười nếu tôi có thể ngừng khóc. Cảm ơn! – MichaelHood

2

Tôi vừa gặp sự cố tương tự here. Chìa khóa takeaway có là cross_val_score sử dụng chiến lược KFold với các thông số mặc định để thực hiện các phân chia kiểm tra đào tạo, có nghĩa là chia thành các khối liên tiếp thay vì xáo trộn. Mặt khác, train_test_split thực hiện phân chia xáo trộn.

Giải pháp là để làm cho chiến lược phân chia rõ ràng và xác định xáo trộn, như thế này:

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

Aniket, cảm ơn câu trả lời. Nhưng việc chỉ định các nếp gấp và chuyển chúng vào cross_val_score không giải quyết sự khác biệt giữa các chỉ số tính điểm. – MichaelHood

+0

Tôi biết tôi rất muộn với điều này, nhưng khi bạn sử dụng phương pháp 'cross_val_score' với điểm số 'roc_auc', tại sao bạn vượt qua nó các nhãn lớp được dự đoán thay vì xác suất dự đoán? Vì nó là AUC, nó không cần xác suất thay vào đó, vì vậy nó có thể kiểm tra các giá trị ngưỡng khác nhau? – NeonBlueHair

0

Tự mình gặp vấn đề này và sau khi tìm hiểu một chút, hãy tìm câu trả lời. Chia sẻ cho tình yêu.

Có hai vấn đề thực sự là một nửa.

  1. bạn cần sử dụng cùng Kfold để so sánh điểm số (cùng một phần của chuyến tàu/bài kiểm tra);
  2. bạn cần phải cấp xác suất vào roc_auc_score (sử dụng phương thức predict_proba()). NHƯNG, một số ước tính (như SVC) không có phương thức predict_proba(), sau đó bạn sử dụng phương thức decision_function().

Dưới đây là một ví dụ đầy đủ:

# 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 

Sử dụng hai ước lượng

LR = LogisticRegression() 
SVM = LinearSVC() 

Chia bộ tàu/kiểm tra. Nhưng giữ nó thành một biến chúng ta có thể tái sử dụng.

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

Cấp nguồn cấp dữ liệu cho GridSearchCV và lưu điểm. Lưu ý rằng chúng tôi đang đi qua 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]) 

Chuyển nó đến cross_val_score và lưu điểm.

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

Đôi khi, bạn muốn lặp lại và tính toán một số điểm khác nhau, vì vậy đây là những gì bạn sử dụng.

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) 

Chúng tôi có cùng điểm số trên bảng không?

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


NHƯNG, đôi khi ước lượng của chúng tôi không có một phương pháp predict_proba(). Vì vậy, theo điều này example, chúng tôi thực hiện việc này:

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) 
Các vấn đề liên quan