1.混淆矩陣
對於分類器而言,乙個比較好的評估指標是混淆矩陣。下面通過乙個**具體展示在二分類器中的應用。
neg(非a)
pos(a)
neg(非a樣本)
90(tn)
10(fp)
pos(a樣本)
30(fn)
70(tp)
其中neg表示非a類,pos表示a類。從**中可以得知,此分類器更能有效地識別非a樣本,而對於a樣本的識別能力不足。
據此我們還可以引出如下概念:
precision和recall都是針對某個類而言的,比如正類別的recall,負類別的recall等。如果你是10分類,那麼可以有1這個類別的precision,2這個類別的precision,3這個類別的recall等。
準確率pre
cesi
on=t
ptp+
fp.\mathcal=\frac.
preces
ion=
tp+f
ptp
.表示你**為正的樣本中有多少**對了。
從這個公式可看出要想使準確率提高,得把fp盡可能的降低,就是降低對非a類的錯誤識別率,也就是說提高對反例的識別率。
召回率rec
all=
tptp
+fn.
\mathcal=\frac.
recall
=tp+
fntp
.表示真實標籤為正的樣本有多少被你**對了。
反之,從這個公式可看出,要想使用召回率提高,得把fn盡可能的降低,就是降低對a類的錯誤識別率,也就是說盡可能的提高正例的識別率。
f1值f1=
tptp
+fn+
fp2.
\mathcal=\frac}.
f1=tp+
2fn+
fpt
p.f1 值是準確率和召回率的調和平均。普通的平均值平等地看待所有的值,而調和平均會給小的值更大的權重。所以,要想分類器得到乙個高的 f1 值,需要召回率和準確率同時高。
f1 支援那些有著相近準確率和召回率的分類器。這不會總是你想要的。有的場景你會絕大程度地關心準確率,而另外一些場景你會更關心召回率。
不幸的是,你不能同時擁有兩者。增加準確率會降低召回率,因為在提高準確率的過程中勢必會增大對反例的識別能力,會把很多似是而非的正例也識別為反例,這樣做必然導致正例的識別率降低,所以召回率也就隨之降低了;反之亦然。這叫做準確率與召回率之間的折衷。
因此針對不同型別的問題,你要有所取捨,在實際編碼過程中,可以通過設定乙個分類相似程度的得分閾值來進行準確率和召回率的調整。
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import cross_val_predict
threshold = 0 #得分閾值
#使用 cross_val_predict() 得到每乙個樣例的分數值,根據這個分數值和閾值進行對比,便可得出每個樣例的分類情況,從而算出其準確率和召回率
#其中method會根據使用的分類演算法不同發生變化,並不是所有的演算法得出的都是分數,要根據實際情況進行調整
#比如隨機森林演算法的method就是乙個概率函式predict_proba,返回的結果是乙個正反例的概率值
y_scores = cross_val_predict(sgd_clf, x_train, y_train_5, cv= 3 , method= "decision_function" )
#得出分數值後,對於任何可能的閾值,使用 precision_recall_curve() ,可以計算出準確率和召回率
precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)
然後通過matplot畫出最終的閾值與曲線的關係圖
from matplotlib import pyplot as plt
def plot_precision_recall_vs_threshold (precisions, recalls, thresholds) :
#precision_recall_curve函式的原始碼中,precision : array, shape = [n_thresholds + 1],the last element is 1
#之所以要通過precisions[: -1 ]使準確率陣列中的最後乙個值刪掉,是因為,隨著閾值的不斷提高,對反例的識別率不斷提高,最終的準確率趨近於1
#但此時的閾值可能太大導致閾值陣列的範圍太大不好表示,所以乾脆就省略了這個閾值,直接令準確率陣列的最後乙個值等於1
plt.plot(thresholds, precisions[: -1 ], "b--" , label= "precision" )
#recalls[: -1 ]意義同上
plt.plot(thresholds, recalls[: -1 ], "g-" , label= "recall" )
plt.xlabel( "threshold" )
plt.legend(loc= "upper left" )
plt.ylim([ 0 , 1 ])
2.pr曲線
最後我們也可以畫出準確率對召回率的曲線(pr曲線),更能準確直觀地反映出在召回率多少時準確率急劇下降。
from matplotlib import pyplot as plt
def plot_precision_vs_recall (precisions, recalls) :
plt.plot(recalls, precisions, "b--" , label= "precision vs recall" )
plt.legend(loc= "upper left" )
plt.ylim([ 0 , 1 ])
如下圖所示,該曲線在80%的召回率時其準確率急劇下降,所以我們應該根據實際情況作出抉擇。最理想的結果是該pr曲線越靠近右上方越好。
3.roc曲線
受試者工作特徵(roc)曲線是另乙個二分類器常用的工具,他其實就是召回率(也叫tpr、recall)對假正例率fpr的關係曲線,fpr 是反例被錯誤分成正例的比率。可以通過roc_curve()函式進行計算。
from sklearn.metrics import roc_curve
fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)
#繪製影象
def plot_roc_curve (fpr, tpr, label=none) :
plt.plot(fpr, tpr, linewidth= 2 , label=label)
plt.plot([ 0 , 1 ], [ 0 , 1 ], 'k--' )
plt.axis([ 0 , 1 , 0 , 1 ])
plt.xlabel( 'false positive rate' )
plt.ylabel( 'true positive rate' )
plot_roc_curve(fpr, tpr)
如下圖所示,召回率(tpr)越高,分類器就會產生越多的假正例(fpr越高,即分類器的準確率降低),這也存在乙個折衷的問題。最理想的情況是roc曲線越靠近左上方越好,其roc aug即roc曲線下面積越大。
4.總結
在平時的二分類評價處理過程中,通常是通過pr曲線與roc曲線來進行指標評價。
roc 曲線跟準確率/召回率曲線(或者叫 pr)很類似,我們有必要對其做乙個歸納總結。
當正例很少或者當你關注假正例多於假反例的時候,優先使用 pr 曲線,其他情況使用 roc 曲線。
PR曲線與ROC曲線
pr曲線中的p代表的是precision 精準率 r代表的是recall 召回率 其代表的是精準率與召回率的關係,一般情況下,將recall設定為橫座標,precision設定為縱座標。在機器學習中,分類器往往輸出的不是類別標號,而是屬於某個類別的概率值,根據分類器的 結果從大到小對樣例進行排序,排...
ROC曲線 PR曲線
在 的結果分析中,roc和pr曲線是經常用到的兩個有力的展示圖。1.roc曲線 roc曲線 receiver operating characteristic 是一種對於靈敏度進行描述的功能影象。roc曲線可以通過描述真陽性率 tpr 和假陽性率 fpr 來實現。由於是通過比較兩個操作特徵 tpr和...
ROC曲線與PR曲線對比
tpr tpp tpt p fn tpr frac frac tpr pt p t p fn tp fpr fpn fpf p tn fpr frac frac fpr nf p f p tn fp roc曲線的縱座標為tpr,真正率,其實也是召回率。分母為所有實際正樣本。roc曲線的縱座標為fpr...