性能度量是指模型泛化能力的衡量糯俗,泛化能力可以理解為對(duì)于未知數(shù)據(jù)的預(yù)判能力
1苫费、回歸場(chǎng)景
(1)均方誤差MSE
回歸預(yù)測(cè)最常用的性能度量是“均方誤差”(MSE mean squared error), 又稱(chēng)為L(zhǎng)2范數(shù)損失。
預(yù)測(cè)值與實(shí)際值的差值平方求和求平均的過(guò)程
實(shí)踐測(cè)試
調(diào)用python的sklearn快速計(jì)算一下荐开。顯然y_pred_2的預(yù)測(cè)效果比y_pred_1效果好,與y_true更接近简肴。
from sklearn.metrics import mean_squared_error
y_true = [3000,1323,4234,6567]
y_pred_1 = [4212,2000,5002,6004]
y_pred_2 = [4124,1252,4341,6534]
print(mean_squared_error(y_true,y_pred_1)) # 708516.5
print(mean_squared_error(y_true,y_pred_2)) # 320238.75
看來(lái)MSE值越小說(shuō)明預(yù)測(cè)能力越好(其實(shí)看公式也能看出來(lái)的)
(2)RMSE
提到均方誤差(MSE晃听,mean squared error)就不能不說(shuō)說(shuō)均方根誤差(RMSE,root mean squared error)
兩者有什么差異嗎砰识?說(shuō)是RMSE消除了對(duì)量綱的影響能扒。
import numpy as np
print(np.sqrt(mean_squared_error(y_true,y_pred_1))) # 841.7342217113428
print(np.sqrt(mean_squared_error(y_true,y_pred_2))) # 565.8964127824102
算法評(píng)估為什么要消除量綱?誤差相關(guān)值不是越小就可以了嗎辫狼?而且做完根號(hào)以后值還是很大的俺醢摺?不多運(yùn)行比較幾次都不知道擬合效果好不好膨处?(解答待定)
(3)
R2(亦稱(chēng)可決系數(shù)越平、確定系數(shù))频蛔,取值范圍在0-1之間,值越大模型的越好秦叛。
from sklearn.metrics import r2_score
y_true = [3000,1323,4234,6567]
y_pred_1 = [4212,2000,5002,6004]
y_pred_2 = [4124,1252,4341,6534]
r2_score(y_true, y_pred_1) # 0.8061345958233034
r2_score(y_true, y_pred_2) # 0.9123757672520116
既然R2那么好用晦溪,但實(shí)際上我們比較常見(jiàn)的還是mse、rmse這類(lèi)性能度量指標(biāo)挣跋,R2有什么局限嗎三圆?(解答待定)
2、分類(lèi)場(chǎng)景
(1)錯(cuò)誤率和精度
錯(cuò)誤率(error rate) = 分類(lèi)錯(cuò)誤數(shù)a/總數(shù)m
精度(accuracy) = 分類(lèi)正確數(shù)1-a/總數(shù)m
- 雖然常用避咆,但局限比較大
- 適用于二分類(lèi)舟肉、多分類(lèi)
# 分為5類(lèi):0,1查库,2路媚,3,4
from sklearn.metrics import accuracy_score
y_true = [0, 2, 1, 3,4,4,3,1,0]
y_pred = [1, 2, 1, 4,2,4,3,2,0] # 4個(gè)分錯(cuò)
accuracy_score(y_true, y_pred) # 0.55555556
(2)TP樊销、FP整慎、TN、FN
預(yù)測(cè)正例 | 預(yù)測(cè)反例 | |
---|---|---|
實(shí)際正例 | TP(true positive) | FN(false negative) |
實(shí)際反例 | FP(false positive) | TN(true negative) |
在TP围苫、FP裤园、TN、FN做文章的相關(guān)性能度量有:查準(zhǔn)率precision剂府、查全率recall拧揽、P-R曲線、ROC曲線腺占、F1
(3)查準(zhǔn)率與查全率
查準(zhǔn)率又叫準(zhǔn)確率淤袜,查全率又叫召回率。
查準(zhǔn)率(準(zhǔn)確率)precision = 衰伯,指所有預(yù)測(cè)為正例的數(shù)據(jù)中铡羡,真正例所占的比例(越大越好)
查全率(召回率)recall = ,指預(yù)測(cè)為正例的數(shù)據(jù)占所有真正例數(shù)據(jù)的比例(越大越好)
from sklearn import metrics
y_true = [0, 1, 1, 0,0,1,0,1,0,0,0,0,1,0,0,0,1]
y_pred = [0, 0, 0, 0,0,1,0,1,0,0,0,0,0,0,1,0,1]
metrics.precision_score(y_true, y_pred, average='binary') # 0.75
metrics.recall_score(y_true, y_pred, average='binary') # 0.5
在準(zhǔn)確率和召回率的基礎(chǔ)上擴(kuò)建的概念有P-R曲線和F1兩個(gè)概念嚎研,與P-R曲線類(lèi)似的有ROC曲線蓖墅。
(4)P-R曲線
以precision為縱軸,recall為橫軸繪制P-R曲線临扮,一般用于模型選擇和參數(shù)調(diào)優(yōu)论矾。
【疑問(wèn)】上面計(jì)算precision和recall不是都只有一個(gè)值嗎?怎么能繪制曲線杆勇?
算法對(duì)樣本進(jìn)行分類(lèi)時(shí)贪壳,都會(huì)有閾值(threshold),我們一般設(shè)置閾值為0.5蚜退,如果預(yù)測(cè)為1的概率大于0.5闰靴,則判斷分類(lèi)結(jié)果為1彪笼,否則分類(lèi)為0。
通過(guò)調(diào)節(jié)閾值蚂且,改變預(yù)測(cè)正例的數(shù)量配猫,從而改變precision和recall的值。詳細(xì)案例可參考P-R曲線過(guò)程如何理解一文杏死。
【參數(shù)調(diào)優(yōu)】因此P-R權(quán)限調(diào)優(yōu)的參數(shù)是這個(gè)“閾值”threshold泵肄,選擇使P-R曲線面積最大的閾值。
【模型選擇】根據(jù)面積與BEP選擇最優(yōu)模型
1)例如模型C的P-R曲線完全被A,B包裹淑翼,顯然AB模型對(duì)于該樣本更合適腐巢。
2)對(duì)于P-R曲線相交的情況,我們比較曲線的平衡點(diǎn)(Break-Event Point, BEP),是準(zhǔn)確率與召回率一致時(shí)的得分玄括,顯然A模型在該樣本上優(yōu)于B模型冯丙。
(5)F1
F1是precision和recall的調(diào)和平均,同時(shí)兼顧了分類(lèi)模型的精確率和召回率,取值范圍在0-1之間遭京,當(dāng)然還是越大越好胃惜。
# P = 0.75; R = 0.5
metrics.f1_score(y_true, y_pred, average='binary') # 0.6
(6)ROC曲線
基本原理與P-R曲線相似,也是通過(guò)改變閾值threshold來(lái)獲得橫軸與縱軸值的變更洁墙,主要在于橫軸與縱軸的變化蛹疯。
【縱軸】縱軸為真正例率(TPR戒财,True positive rate热监,真陽(yáng)率)
可以發(fā)現(xiàn)Recall = TPR(當(dāng)然P-R曲線縱軸是P,橫軸是R),這里TPR為縱軸饮寞。真正例率孝扛,越大越好。
【橫軸】橫軸為假正例率(FPR幽崩,F(xiàn)alse positive rate苦始,假陽(yáng)率)
假正例率,當(dāng)然是值越小越好
【ROC曲線】
怎樣理解ROC曲線呢慌申?先來(lái)看一下四個(gè)頂點(diǎn)(0,0)陌选,(0,1),(1,0)蹄溉,(1,1)
(0,0)咨油,F(xiàn)PR=0,TPR=0,即TP=0,FP=0,實(shí)際為正例的預(yù)測(cè)為反例柒爵,實(shí)際為反例的也全預(yù)測(cè)為反例役电,即該模型對(duì)正例的預(yù)測(cè)無(wú)效。
(0,1)棉胀,F(xiàn)PR=0,TPR=1,即FP=0,FN=0法瑟,那就是實(shí)際為正例的全部預(yù)測(cè)為正例冀膝,實(shí)際為反例的全部預(yù)測(cè)為反例,最完美的模式霎挟。
(1,0)窝剖,F(xiàn)PR=1,TPR=0,即TN=0,TP=0,不管正例反例都沒(méi)判斷對(duì)
(1,1)酥夭,F(xiàn)PR=1,TPR=1,即TN=0,FN=0枯芬,實(shí)際為正例的預(yù)測(cè)為正例,實(shí)際為反例的也全預(yù)測(cè)為正例采郎,即該模型對(duì)反例的預(yù)測(cè)無(wú)效千所。
使用AUC(Area Under ROC Curve)描述曲面下的面積,AUC值越大表示模型的預(yù)測(cè)能力越好蒜埋。
三淫痰、多分類(lèi)場(chǎng)景
對(duì)于多分類(lèi)場(chǎng)景,可以使用哪些性能衡量指標(biāo)呢整份?
性能度量指標(biāo) | 描述 | 是否適用多分類(lèi) |
---|---|---|
accuracy | 預(yù)測(cè)正確/總量 | yes |
error | 預(yù)測(cè)錯(cuò)誤/總量 | yes |
precision | 轉(zhuǎn)型升級(jí) | yes |
recall | 轉(zhuǎn)型升級(jí) | yes |
F1 | 轉(zhuǎn)型升級(jí) | yes |
ROC | 轉(zhuǎn)型升級(jí) | yes |
多分類(lèi)問(wèn)題除了accuracy和error的衡量外待错,也有precision、recall烈评、F1的度量火俄,不過(guò)需要做個(gè)轉(zhuǎn)型升級(jí)。
(1)macro宏
先計(jì)算出每個(gè)分類(lèi)的precision讲冠、recall瓜客、F1,然后計(jì)算平均值竿开,作為該模型對(duì)多分類(lèi)的macro-P谱仪、macro-R、macro-F1否彩。
結(jié)合代碼按步驟進(jìn)行計(jì)算
計(jì)算案例的macro-P疯攒、macro-R、macro-F1
1列荔、把目標(biāo)類(lèi)設(shè)置為1敬尺,其他為0,模擬每個(gè)類(lèi)的二分類(lèi)場(chǎng)景
2贴浙、計(jì)算每個(gè)類(lèi)的P砂吞、R、F1
3悬而、macro-P呜舒、macro-R、macro-F1為均值
具體代碼參見(jiàn)附錄macro-P笨奠、macro-R袭蝗、macro-F1唤殴,計(jì)算結(jié)果為macro-P = 0.6389,macro-R= 0.5633到腥、macro-F1=0.5790
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_score,recall_score,f1_score
y_true = [0, 2, 1, 3,4,4,3,1,0,0,0,1,1,2,3,2,2,4,2,1]
y_pred = [1, 2, 1, 4,2,4,3,2,0,0,0,1,2,3,2,2,2,2,2,1]
confusion_matrix(y_true,y_pred)
precision_score(y_true,y_pred,labels=[0,1,2,3,4],average='macro') # 0.638888888888889
recall_score(y_true,y_pred,labels=[0,1,2,3,4],average='macro') # 0.5633333333333335
f1_score(y_true,y_pred,labels=[0,1,2,3,4],average='macro') # 0.5790476190476189
和直接調(diào)用sklearn結(jié)果是一樣的朵逝。
(2)micro微
先計(jì)算出每個(gè)分類(lèi)的TP,TN,FP,FN,然后獲得TP,TN,FP,FN的平均值乡范,帶入precision配名、recall、F1的計(jì)算公式即可獲得micro-P晋辆、micro-R渠脉、micro-F1
結(jié)合代碼按步驟進(jìn)行計(jì)算
計(jì)算案例的micro-P、micro-R瓶佳、micro-F1
1芋膘、把目標(biāo)類(lèi)設(shè)置為1,其他為0霸饲,模擬每個(gè)類(lèi)的二分類(lèi)場(chǎng)景
2为朋、計(jì)算每個(gè)類(lèi)的TP,TN,FP,FN
3、計(jì)算每個(gè)類(lèi)的TP,TN,FP,FN均值
4厚脉、帶入公式习寸,計(jì)算micro-P、micro-R傻工、micro-F1
具體代碼參見(jiàn)附錄macro-P霞溪、macro-R、macro-F1精钮,計(jì)算結(jié)果為micro-P = 0.6威鹿,micro-R= 0.6剃斧、micro-F1=0.6轨香,與直接調(diào)用sklearn計(jì)算結(jié)果一致
# micro微
precision_score(y_true,y_pred,labels=[0,1,2,3,4],average='micro')
recall_score(y_true,y_pred,labels=[0,1,2,3,4],average='micro')
f1_score(y_true,y_pred,labels=[0,1,2,3,4],average='micro')
(3)多分類(lèi)的ROC曲線
多分類(lèi)問(wèn)題可以把目標(biāo)類(lèi)設(shè)置為1,其他為0幼东,模擬每個(gè)類(lèi)的二分類(lèi)場(chǎng)景臂容。
- macro-roc:對(duì)n條ROC曲線取平均,即可得到最終的ROC曲線
- micro-roc:對(duì)每一類(lèi)TP,TN,FP,FN取均值根蟹,然后計(jì)算TPR,FPR
多分類(lèi)ROC曲線一文寫(xiě)的挺清楚的
但感覺(jué)多分類(lèi)的roc曲線用起來(lái)一點(diǎn)也不方便脓杉,不像二分類(lèi)的ROC一個(gè)函數(shù)解決,有點(diǎn)麻煩不是很想用
【問(wèn)題】
- 某些性能度量是不是只有二分類(lèi)場(chǎng)景可以用简逮?
- 準(zhǔn)確率與精度的概念紊亂
accuracy = 分類(lèi)正確數(shù)/總數(shù)球散,叫精度
precision = TP/(TP+FP) ,叫準(zhǔn)確率 - 那么多性能衡量指標(biāo)要怎么選散庶?適用什么場(chǎng)景蕉堰?一般使用那個(gè)數(shù)值衡量模型凌净?
例如PR曲線的兩個(gè)指標(biāo)(TPR真正例率,FPR假正例率)都聚焦于正例,主要關(guān)心正例屋讶,對(duì)于類(lèi)別不平衡冰寻、比較關(guān)系正例判斷能力的時(shí)候比較適用
四、聚類(lèi)場(chǎng)景
聚類(lèi)算法的性能衡量指標(biāo)是什么皿渗?不像有監(jiān)督學(xué)習(xí)那樣可以根據(jù)標(biāo)簽計(jì)算accuracy斩芭、error等值。
聚類(lèi)是將樣本劃分為若干互不相交的子集乐疆,簇內(nèi)相似度高划乖,簇間相似度低。聚類(lèi)的性能度量指標(biāo)分為外部指標(biāo)和內(nèi)部指標(biāo)
聚類(lèi)性能度量 | 指標(biāo)名稱(chēng) |
---|---|
外部指標(biāo) | jaccard系數(shù)(jaccard coefficient,JC) |
FM指數(shù)(fowlkes and Mallows Index, FMI) | |
Rand指數(shù)(Rand Index, RI) | |
內(nèi)部指標(biāo) | DB指數(shù) |
Dunn指數(shù) |
詳細(xì)性能度量指標(biāo)可以參考聚類(lèi)性能度量和距離計(jì)算一文挤土。
參考資料
[1]《機(jī)器學(xué)習(xí)》周志華
[2] P-R曲線過(guò)程如何理解:https://www.zhihu.com/question/348073311/answer/837781413
[3] 聚類(lèi)的性能度量:https://blog.csdn.net/qq_36396104/article/details/78166317
附錄
1迁筛、precision與recall的計(jì)算
import numpy as np
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
y_true = [0, 1, 1, 0,0,1,0,1,0,0,0,0,1,0,0,0,1]
y_pred = [0, 0, 0, 0,0,1,0,1,0,0,0,0,0,0,1,0,1]
accuracy_score(y_true, y_pred)
confusion_matrix(y_true,y_pred)
# 判斷為1實(shí)際也為1
TP = np.sum(np.logical_and(np.equal(y_true,1),np.equal(y_pred,1)))
# 判斷為0實(shí)際也為0
TN = np.sum(np.logical_and(np.equal(y_true,0),np.equal(y_pred,0)))
# 判斷為1實(shí)際為0
FP = np.sum(np.logical_and(np.equal(y_true,0),np.equal(y_pred,1)))
# 判斷為0實(shí)際為1
FN = np.sum(np.logical_and(np.equal(y_true,1),np.equal(y_pred,0)))
precision = TP/(TP+FP) # 0.75
recall = TP/(TP+FN) # 0.5
2、macro-P耕挨、macro-R细卧、macro-F1
# 數(shù)據(jù)處理:把目標(biāo)類(lèi)設(shè)置為1,其他為0筒占,模擬該類(lèi)的二分類(lèi)
def deal_list(y,labels):
new_list = []
for i in y:
if i==labels:
new_list.append(1)
else:
new_list.append(0)
return new_list
# 計(jì)算目標(biāo)類(lèi)的P贪庙、R、F1
def count_p_r_f1(y_true,y_pred,labels):
new_true = deal_list(y_true,labels)
new_pred = deal_list(y_pred,labels)
a = precision_score(new_true, new_pred, average='binary')
b = recall_score(new_true, new_pred, average='binary')
c = f1_score(new_true, new_pred, average='binary')
return a,b,c
y_true = [0, 2, 1, 3,4,4,3,1,0,0,0,1,1,2,3,2,2,4,2,1]
y_pred = [1, 2, 1, 4,2,4,3,2,0,0,0,1,2,3,2,2,2,2,2,1]
p_score = []
r_score = []
f1 = []
for i in range(5):
a,b,c = count_p_r_f1(y_true,y_pred,i)
p_score.append(a)
r_score.append(b)
f1.append(c)
# 計(jì)算macro-P,macro-R,macro-F1
def count_mean(score_list):
s = sum(score_list)/len(score_list)
return s
count_mean(p_score) # 0.638888888888889
count_mean(r_score) # 0.5633333333333335
count_mean(f1) # 0.5790476190476189
3翰苫、 計(jì)算micro-P,micro-R,micro-F1
import numpy as np
def count_tp_tn_fp_fn(new_true,new_pred):
# 判斷為1實(shí)際也為1
TP = np.sum(np.logical_and(np.equal(new_true,1),np.equal(new_pred,1)))
# 判斷為0實(shí)際也為0
TN = np.sum(np.logical_and(np.equal(new_true,0),np.equal(new_pred,0)))
# 判斷為1實(shí)際為0
FP = np.sum(np.logical_and(np.equal(new_true,0),np.equal(new_pred,1)))
# 判斷為0實(shí)際為1
FN = np.sum(np.logical_and(np.equal(new_true,1),np.equal(new_pred,0)))
return TP,TN,FP,FN
y_true = [0, 2, 1, 3,4,4,3,1,0,0,0,1,1,2,3,2,2,4,2,1]
y_pred = [1, 2, 1, 4,2,4,3,2,0,0,0,1,2,3,2,2,2,2,2,1]
TP_list,TN_list,FP_list,FN_list = [],[],[],[]
for i in range(5):
new_true = deal_list(y_true,i)
new_pred = deal_list(y_pred,i)
TP,TN,FP,FN = count_tp_tn_fp_fn(new_true,new_pred)
TP_list.append(TP)
TN_list.append(TN)
FP_list.append(FP)
FN_list.append(FN)
TP_mean = count_mean(TP_list)
TN_mean = count_mean(TN_list)
FP_mean = count_mean(FP_list)
FN_mean = count_mean(FN_list)
precision = TP_mean/(TP_mean+FP_mean) # 0.6
recall = TP_mean/(TP_mean+FN_mean) # 0.6
f1 = 2*precision*recall/(precision+recall) # 0.6