機器學習中對分類器的評估參考以下的評價指標,主要包括準確率(Accuracy),精確率(Precision),召回率(Recall),F1-Score。接下來的描述主要是以二分類舉例,即label爲0和1的情況。
(一)理解TP, TN, FP, FN
首先需要明確這幾個值的定義:
True Positive(真正, TP):將正類預測爲正類數.
True Negative(真負, TN):將負類預測爲負類數.
False Positive(假正, FP):將負類預測爲正類數 →→ 誤報 (Type I error).
False Negative(假負 , FN):將正類預測爲負類數 →→ 漏報 (Type II error).
即:
Positive | Negative | |
True | TP | FP |
False | FN | TN |
用代碼直觀的表示,如下:
if (pred.view_as(data == 1) & (data.detach().cpu() == 1):
# TP predict & label == 1
tp += 1
if (pred.view_as(data == 0) & (data.detach().cpu() == 0):
# TN predict & label == 0
tn += 1
if (pred.view_as(data == 1) & (data.detach().cpu() == 0):
# FN predict == 0 & label == 1
fn += 1
fn_list.append(np.array(data.detach().cpu()))
if (pred.view_as(data == 0) & (data.detach().cpu() == 1):
# FP predict == 1 & label == 0
fp += 1
fp_list.append(np.array(data.detach().cpu()))
(二)理解準確率(Accuracy)和精確率(Precision)
精確率(precision)和準確率(accuracy)是不一樣的,我們在做模型評估是需要搞清楚兩者的定義。
準確率是針對我們原來所有樣本而言的,它表示的是所有樣本有多少被準確預測了,即:
Acc = (tp + tn) / (tp + tn + fp + fn)
精確率是針對我們預測結果而言的,它表示的是預測爲正的樣本中有多少是真正的正樣本。那麼預測爲正就有兩種可能了,一種就是把正類預測爲正類(TP),另一種就是把負類預測爲正類(FP),即:
P = tp / (tp + fp)
“ 預測爲正例的裏面有多少是對的”。
(三)理解精確率(Precision)和召回率(Recall)
召回率是針對我們原來的正樣本而言的,它表示的是正例樣本中有多少被預測正確了。那也有兩種可能,一種是把原來的正類預測成正類(TP),另一種就是把原來的正類預測爲負類(FN)。即:
R = tp / (tp + fn)
準確率和召回率是廣泛用於信息檢索和統計學分類領域的兩個度量值,用來評價結果的質量。其中精度是檢索出相關文檔數與檢索出的文檔總數的比率,衡量的是檢索系統的查準率;召回率是指檢索出的相關文檔數和文檔庫中所有的相關文檔數的比率,衡量的是檢索系統的查全率。
一般來說,Precision就是檢索出來的條目(比如:文檔、網頁等)有多少是準確的,Recall就是所有準確的條目有多少被檢索出來了。
正確率、召回率和 F 值是在魚龍混雜的環境中,選出目標的重要評價指標。不妨看看這些指標的定義先:
1. 正確率 = 提取出的正確信息條數 / 提取出的信息條數
2. 召回率 = 提取出的正確信息條數 / 樣本中的信息條數
兩者取值在0和1之間,數值越接近1,查準率或查全率就越高。
(四)理解F1-Score
F1分數(F1-score)是分類問題的一個衡量指標。一些多分類問題的機器學習競賽,常常將F1-score作爲最終測評的方法。它是精確率和召回率的調和平均數,最大爲1,最小爲0。
F1的計算:F1-score = 2 ∗ Precision ∗ Recall / (Precision + Recall)
(五)使用sklearn庫來實現模型評估 (以下提供計算方法)
使用pip命令下載安裝sklearn庫
pip install scikit-learn
1. 使用tn,fp,fn,tp來計算相應的指標
from sklearn.metrics import confusion_matrix
def test(self):
self.model.load_weights(self.name + "_model.pkl")
values = self.model.evaluate(self.x_test, self.y_test, batch_size=self.batch_size)
print("Accuracy: ", values[1])
predictions = (self.model.predict(self.x_test, batch_size=self.batch_size)).round()
tn, fp, fn, tp = confusion_matrix(np.argmax(self.y_test, axis=1), np.argmax(predictions, axis=1)).ravel()
print('False positive rate(FP): ', fp / (fp + tn))
print('False negative rate(FN): ', fn / (fn + tp))
recall = tp / (tp + fn)
print('Recall: ', recall)
precision = tp / (tp + fp)
print('Precision: ', precision)
print('F1 score: ', (2 * precision * recall) / (precision + recall))
2. 直接計算 recall和precision
from sklearn import metrics
def test(test_loader):
model.eval()
start = time.time()
test_loss, correct, n_samples, count = 0, 0, 0, 0
accuracy, recall, precision, F1 = 0, 0, 0, 0
for batch_idx, data in enumerate(test_loader):
count += 1
for i in range(len(data)):
data[i] = data[i].to(args.device)
output = model(data)
loss = loss_fn(output, data[4], reduction='sum')
test_loss += loss.item()
n_samples += len(output)
pred = output.detach().cpu().max(1, keepdim=True)[1]
correct += pred.eq(data[4].detach().cpu().view_as(pred)).sum().item()
accuracy += metrics.accuracy_score(data[4], pred)
recall += metrics.recall_score(data[4], pred, average="macro")
precision += metrics.precision_score(data[4], pred, average="macro")
F1 += metrics.f1_score(data[4], pred, average="macro")
acc = 100. * correct / n_samples
accuracy = 100. * accuracy / count
recall = 100. * recall / count
precision = 100. * precision / count
F1 = 100. * F1 / count
關於上述的具體代碼,可以參考: