摘要:的實(shí)現(xiàn)如下表示真實(shí)分類,表示預(yù)測結(jié)果混淆矩陣的結(jié)果為中封裝了混淆矩陣方法精準(zhǔn)率和召回率及實(shí)現(xiàn)有了混淆矩陣,精準(zhǔn)率和召回率久很好表示了。就是召回率,即表示真實(shí)分類偏斜數(shù)據(jù)中占優(yōu)勢的分類中被預(yù)測錯誤的數(shù)量的占比,即。
以邏輯回歸為例,介紹分類結(jié)果的評價方式。
精準(zhǔn)率和召回率對于極度偏斜的數(shù)據(jù),使用分類準(zhǔn)確度來評判模型的好壞是不恰當(dāng)?shù)?,精確度和召回率是兩個更好的指標(biāo)來幫助我們判定模型的好快。
二分類的混淆矩陣精準(zhǔn)率和召回率是存在于混淆矩陣之上的,以二分類為例,分類0是偏斜數(shù)據(jù)中占優(yōu)勢的一方,將關(guān)注的重點(diǎn)放在分類為1上,其混淆矩陣如下:
真實(shí)值預(yù)測值 | 0 | 1 |
---|---|---|
0 | 9978(TN) | 12(FP) |
1 | 2(FN) | 8(TP) |
TN 的含義是預(yù)測 negative 正確的數(shù)量,即真實(shí)分類為0預(yù)測的分類結(jié)果也為0的共有9978個;
FN 的含義是預(yù)測 negative 錯誤的數(shù)量,即真實(shí)分類為1預(yù)測的分類結(jié)果為0的共有2個;
FP 的含義是預(yù)測 positive 錯誤的數(shù)量,即真實(shí)分類為0預(yù)測的分類結(jié)果為1的共有12個;
TP 的含義是預(yù)測 positive 正確的數(shù)量,即真實(shí)分類為1預(yù)測的分類結(jié)果也為1的共有8個。
TN、FN、FP、TP 的實(shí)現(xiàn)如下(y_true 表示真實(shí)分類, y_predict 表示預(yù)測結(jié)果):
import numpy as np def TN(y_true, y_predict): return np.sum((y_true == 0) & (y_predict == 0)) def FP(y_true, y_predict): return np.sum((y_true == 0) & (y_predict == 1)) def FN(y_true, y_predict): return np.sum((y_true == 1) & (y_predict == 0)) def TP(y_true, y_predict): return np.sum((y_true == 1) & (y_predict == 1))
混淆矩陣的結(jié)果為:
def confusion_matrix(y_test, y_predict): return np.array([ [TN(y_test, y_log_predict), FP(y_test, y_log_predict)], [FN(y_test, y_log_predict), TP(y_test, y_log_predict)] ])
Scikit Learn 中封裝了混淆矩陣方法 confusion_matrix():
from sklearn.metrics import confusion_matrix confusion_matrix(y_true, y_predict)精準(zhǔn)率和召回率及實(shí)現(xiàn)
有了混淆矩陣,精準(zhǔn)率和召回率久很好表示了。
精準(zhǔn)率表示預(yù)測分類結(jié)果中預(yù)測正確的數(shù)量的占比,即:
$$ precision=frac{TP}{TP+FP} $$
將其用代碼表示為:
def precision_score(y_true, y_predict): tp = TP(y_true, y_predict) fp = FP(y_true, y_predict) try: return tp / (tp + fp) except: return 0.0
召回率表示真實(shí)分類中被預(yù)測正確的數(shù)量的占比,即:
$$ recall=frac{TP}{TP+FN} $$
將其用代碼表示為:
def recall_score(y_true, y_predict): tp = TP(y_true, y_predict) fn = FN(y_true, y_predict) try: return tp / (tp + fn) except: return 0.0
Scikit Learn 中也封裝了計(jì)算精準(zhǔn)率的方法 precision_score() 和計(jì)算召回率的方法 recall_score():
from sklearn.metrics import precision_score precision_score(y_true, y_predict) from sklearn.metrics import recall_score recall_score(y_true, y_predict)F1 Score
精準(zhǔn)率和召回率這兩個指標(biāo)的側(cè)重點(diǎn)不同,有的時候我們注重精準(zhǔn)率(如股票預(yù)測),有的時候我們注重召回率(病人診斷)。但有時候又需要把兩者都考慮進(jìn)行,此后就可以使用 F1 Score 指標(biāo)。
F1 Score 是精準(zhǔn)率和召回率的調(diào)和平均值,公式為:
$$ frac{1}{F1}=frac{1}{2}(frac{1}{precision}+frac{1}{recall}) $$
即:$F1=frac{2·precision·recall}{precesion+recall}$,并且 F1 Score 的取值是在區(qū)間 $[0, 1]$ 之中的。
代碼實(shí)現(xiàn)為:
def f1_score(y_true, y_predict): precision = precision_score(y_true, y_predict) recall = recall_score(y_true, y_predict) try: return 2 * precision * recall / (precision + recall) except: return 0.0
Scikit Learn 中封裝了方法 f1_score() 來計(jì)算 F1 Score:
from sklearn.metrics import f1_score f1_score(y_true, y_predict)Precision-Recall 曲線
Scikit Learn 的邏輯回歸中的概率公式為 $hat p=sigma( heta^T·x_b)$ ,其決策邊界為 $ heta^T·x_b=0$,但是如果決策邊界不為0會如何呢?
假定決策邊界為 $ heta^T·x_b=threshold$,當(dāng) threshold 的取值不同(0、大于0的某個值、小于0的某個值),對應(yīng)的精確度和召回率也不同。如圖:
圓形和星形是不同的的分類,并且重點(diǎn)放在星形的分類上,可以看出,threshold 的取值越大時,精確率越高,而召回率越低。
如果要更改決策邊界,邏輯回歸的 decision_function() 返回傳入數(shù)據(jù)的 $ heta^T·x_b$ 計(jì)算結(jié)果 decision_scores,接著再構(gòu)建一個新的預(yù)測結(jié)果;如代碼所示,設(shè)定 decision_scores >= 5(默認(rèn)decision_scores >= 0 ) 的預(yù)測結(jié)果才為1,其余為0:
from sklearn.linear_model import LogisticRegression log_reg = LogisticRegression() # X_train, y_train 為訓(xùn)練數(shù)據(jù)集 log_reg.fit(X_train, y_train) # X_test,y_test 為測試數(shù)據(jù)集 decision_scores = log_reg.decision_function(X_test) y_log_predict_threshold = np.array(decision_scores >= 5, dtype="int")
如此可以得到不同的 y_log_predict_threshold,進(jìn)而得到不同的精準(zhǔn)率和召回率。
以手寫數(shù)字識別數(shù)據(jù)為例,將標(biāo)記為9的數(shù)據(jù)分類為1,其余分類為0:
from sklearn import datasets digits = datasets.load_digits() X = digits.data y = digits.target.copy() y[digits.target==9] = 1 y[digits.target!=9] = 0 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=500)
接著訓(xùn)練邏輯回歸模型:
from sklearn.linear_model import LogisticRegression log_reg = LogisticRegression() log_reg.fit(X_train, y_train)
獲取測試數(shù)據(jù)集 X_test 對應(yīng)的 $ heta^T·x_b$ 取值:
decision_scores = log_reg.decision_function(X_test)
在 decision_scores 的取值區(qū)間劃分為一系列值 thresholds ,并將其中的值依次作為決策邊界,進(jìn)而得到不同的精確率和召回率
from sklearn.metrics import precision_score from sklearn.metrics import recall_score precisions = [] recalls = [] thresholds = np.arange(np.min(decision_scores), np.max(decision_scores), 0.1) for threshold in thresholds: y_predict = np.array(decision_scores >= threshold, dtype="int") precisions.append(precision_score(y_test, y_predict)) recalls.append(recall_score(y_test, y_predict))
將精確率、召回率與決策邊界的關(guān)系繪制如圖:
精確度與召回率的關(guān)系,即 Precision-Recall 曲線則為:
Scikit Learn 中提供的 precision_recall_curve() 方法傳入真實(shí)分類結(jié)果和 decision_scores,返回 precisions、recalls 和 thresholds:
from sklearn.metrics import precision_recall_curve precisions, recalls, thresholds = precision_recall_curve(y_test, decision_scores)
Precision-Recall 曲線越靠外(即面積越大)則表示模型越好。
多分類中的精確率和召回率在過分類中,Sckit Learn 提供的 confusion_matrix() 可以直接返回多分類的混淆矩陣,而對于精確率和召回率,則要在 Sckit Learn 提供的方法中指定 average 參數(shù)值為 micro,如:
from sklearn.metrics import precision_score precision_score(y_test, y_predict, average="micro")ROC 曲線
對于用圖形面積判斷模型好快,ROC 曲線比 Precision-Recall 曲線要好。
ROC 曲線涉及兩個指標(biāo),TPR 和 FPR。TPR 就是召回率,即:$TPR=frac{TP}{TP+FN}$;FPR 表示真實(shí)分類(偏斜數(shù)據(jù)中占優(yōu)勢的分類)中被預(yù)測錯誤的數(shù)量的占比,即:$FPR=frac{FP}{TN+FP}$。實(shí)現(xiàn)代碼為:
def TPR(y_true, y_predict): tp = TP(y_true, y_predict) fn = FN(y_true, y_predict) try: return tp / (tp + fn) except: return 0.0 def FPR(y_true, y_predict): fp = FP(y_true, y_predict) tn = TN(y_true, y_predict) try: return fp / (fp + tn) except: return 0.0
對于決策邊界的不同,這兩個指標(biāo)的變化趨勢是一致的。還是以上面的手寫數(shù)字識別數(shù)據(jù)為例,計(jì)算不同決策邊界下的兩指標(biāo)的值為:
fprs = [] tprs = [] for threshold in thresholds: y_predict = np.array(decision_scores >= threshold, dtype="int") fprs.append(FPR(y_test, y_predict)) tprs.append(TPR(y_test, y_predict))
作出的 TPR 和 FPR 的關(guān)系圖(即 ROC 曲線)為:
Scikit Learn 中提供的 roc_curve() 方法傳入真實(shí)分類結(jié)果和 decision_scores,返回 TPR、FPR 和 thresholds:
from sklearn.metrics import roc_curve fprs, tprs, thresholds = roc_curve(y_test, decision_scores)
roc_auc_score() 方法傳入真實(shí)分類結(jié)果和 decision_scores,返回 ROC 曲線表示的面積。
from sklearn.metrics import roc_auc_score roc_auc_score(y_test, decision_scores)
面積越大,則模型越好。
源碼地址Github | ML-Algorithms-Action
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42791.html
閱讀 2280·2019-08-30 15:56
閱讀 3115·2019-08-30 13:48
閱讀 1128·2019-08-30 10:52
閱讀 1497·2019-08-29 17:30
閱讀 426·2019-08-29 13:44
閱讀 3548·2019-08-29 12:53
閱讀 1117·2019-08-29 11:05
閱讀 2671·2019-08-26 13:24