![](/img/trans.png)
[英]What is the score function formula of sklearn.model_selection.cross_val_score?
[英]sklearn.model_selection.cross_val_score has different results from a manual calculation done on a confusion matrix
TL;DR 當我通過 CV cross_val_score()
計算精度、召回率和 f1 時,它給我的結果與通過混淆矩陣計算時不同。 為什么它給出不同的精度、召回率和 f1 分數?
我正在學習機器學習中的 SVM,我想比較cross_val_score
返回的結果和我從混淆矩陣中手動計算指標得到的結果。 但是,我有不同的結果。
首先,我使用cross_val_score
編寫了下面的代碼。
clf = svm.SVC()
kfold = KFold(n_splits = 10)
accuracy = metrics.make_scorer(metrics.accuracy_score)
precision = metrics.make_scorer(metrics.precision_score, average = 'macro')
recall = metrics.make_scorer(metrics.recall_score, average = 'macro')
f1 = metrics.make_scorer(metrics.f1_score, average = 'macro')
accuracy_score = cross_val_score(clf, X, y, scoring = accuracy, cv = kfold)
precision_score = cross_val_score(clf, X, y, scoring = precision, cv = kfold)
recall_score = cross_val_score(clf, X, y, scoring = recall, cv = kfold)
f1_score = cross_val_score(clf, X, y, scoring = f1, cv = kfold)
print("accuracy score:", accuracy_score.mean())
print("precision score:", precision_score.mean())
print("recall score:",recall_score.mean())
print("f1 score:", f1_score.mean())
每個指標的結果如下所示:
accuracy score: 0.97
precision score: 0.96
recall score: 0.97
f1 score: 0.96
此外,我創建了一個混淆矩陣,以便我可以根據矩陣上的值手動計算准確率、精度、召回率和 f1 分數。 我手動創建了混淆矩陣,因為我使用的是 K 折交叉驗證。 為此,我必須為交叉驗證的每次迭代獲取實際類和預測類,因此我有以下代碼:
def cross_val_predict(model, kfold : KFold, X : np.array, y : np.array) -> Tuple[np.array, np.array]:
model_ = cp.deepcopy(model)
# gets the number of classes in the column/attribute
no_of_classes = len(np.unique(y))
# initializing empty numpy arrays to be returned
actual_classes = np.empty([0], dtype = int)
predicted_classes = np.empty([0], dtype = int)
for train_index, test_index in kfold.split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
# append the actual classes for this iteration
actual_classes = np.append(actual_classes, y_test)
# fit the model
model_.fit(X_train, y_train)
# predict
predicted_classes = np.append(predicted_classes, model_.predict(X_test))
return actual_classes, predicted_classes
之后,我在調用上述函數后創建了我的混淆矩陣。
actual_classes, predicted_classes = cross_val_predict(clf, kfold, X, y)
cm = metrics.confusion_matrix(y_true = actual_classes, y_pred = predicted_classes)
cm_display = metrics.ConfusionMatrixDisplay(confusion_matrix = cm, display_labels = [2,4])
cm_display.plot()
現在,我的混淆矩陣如下所示:
where: col is the predicted label, and row is the true label.
|------|------|
2 | 431 | 13 |
|------|------|
4 | 9 | 230 |
|------|------|
2 4
如果我從該矩陣手動計算准確率、精度、召回率和 f1 分數,我有 ff:
confusion matrix accuracy: 0.97
confusion matrix precision: 0.95
confusion matrix recall: 0.96
confusion matrix f1 score: 0.95
我的問題是,為什么我從混淆矩陣中手動計算指標得到不同的結果,而在指定要使用哪個記分器時調用cross_val_score
得到不同的結果,即 [accuracy,precision,recall,fscore]。
我希望你們能幫助我理解為什么。 非常感謝您的回復!
使用cross_val_score
,您可以獲取在每個折疊上計算的指標的平均值,但是當您手動執行此操作時,您會在計算分數之前連接預測。 因此,修改了 F1 分數、精度,而准確率和召回率不受影響。
如果 n 是您擁有的樣本數,而 k 是折疊數,那么您可以編寫:
從這個等式可以看出,在每個折疊大小相同的情況下,對准確率求平均值就相當於計算全局平均值。 但是,如果某些折疊具有不同的大小,則情況並非如此。 但是由於差異僅是一個參與者的最大值,並且與數據集大小相比,一個參與者通常很小,所以折疊平均值和整個預測精度的計算值之間的差異是不同的。
現在讓我們考慮精度(但對於從兩個精度計算的 f1 分數或 ROC AUC 也是如此); 這是真陽性/陽性預測的比率
假設你有 3 折:
折疊 1 :4 個正預測,1 個真正:精度 = 1/4
折疊 2 :2 個正預測,2 個真正:精度 = 1
折疊 3 :3 個正預測,1 個真正:精度 = 1/3
現在,如果您取平均值,您將獲得19/36=0.527的精度。 但是,如果您得到一些正面預測和真實正面的數量,您會得到4/9=0.44 ,這是完全不同的。
不同之處在於分母,即你的積極預測的數量,在折疊上不是恆定的。 取平均值時,極值的影響更大。
召回率是True positive/Positive samples的比率。 在您對 k 折進行分層的情況下,平均值應與您的級聯指標相同。
這是一個我還沒有找到明確答案的問題。 大多數框架或定義都使用分數的平均值,但我沒有發現任何與計算所有預測的指標的比較,所以這里有一些個人觀察:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.