做過機器學習項目的同學大多都用過f1-score, 這是一種均衡精度(precision)和召回率(recall)的綜合評價指標,但為什么不用平均值呢?
精度和召回率
精度
$$ pre = \frac{tp}{tp+fp}$$
tp: true positive 真正例,即預測為正例真實也為正例的個數;
fp: false positive 假正例,即預測為正例但實際是反例的個數;
precision 評價的是查准率,即給出的預測為正例中多少是正確的。
召回率
$$ recall = \frac{tp}{tp+fn}$$
tn: false negative 假反例,即真實是正例,(tp+fn)表示總共的正例個數。
recall 評價的是查全率,即模型正確召回了多少的正例。
f1-score 和平均值
$$ mean = \frac{pre+recall}{2} $$
$$ f1\_score = \frac{1}{\frac{1}{recall}+{\frac{1}{pre}}} = \frac{2*pre*recall}{pre+recall}$$
f1-score的公式可以看出recall或者pre較小的那個將會決定f1-score結果,即具有短板效應,而均值的方法不具有這樣的效果。例如$recall=1,pre \approx 0$的情況下$f1\_score \approx 0; mean \approx 0.5$。
總結一下,就是f1-score比均值的方法更能說明一個模型的好壞,因為很多時候都需要recall和pre的均衡,任意一個指標太差都是無法接受的。
可視化結果
下圖是這兩種指標的可視化結果,x軸和y軸分別代表recall和pre,z軸代表綜合評價指標(evaluation metric),藍色的平面為均值在不同的精度和召回率下(0-1)的結果,變色的曲面表示f1-score在不同精度和召回率下(0-1)的結果。
可以看到在對角線部分兩者是重合的,但是靠近兩邊時,f1-score下降很厲害,直至0,而均值並沒有這樣的效果。
代碼:
# 載入模塊 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 創建 3D 圖形對象 fig = plt.figure() ax = Axes3D(fig) # 生成數據 X = np.arange(0.0001, 1, 0.01) Y = np.arange(0.0001, 1, 0.01) X, Y = np.meshgrid(X, Y) mean = (X+Y)/2 f1_score = 2*(X*Y)/(X+Y) ax.set_xlabel('recall') ax.set_ylabel('precision') ax.set_zlabel('evaluation metric') # 繪制曲面圖,並使用 cmap 着色 ax.plot_surface(X, Y, mean, cmap=plt.cm.winter) ax.plot_surface(X, Y, f1_score, cmap='rainbow') plt.show()