- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564695 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174631
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
3 Y6 g7 O4 T* o- z$ b
详细讲解分类模型评估分类模型评估3 `! e* N5 @4 S3 q U% r
9 ~1 W6 U# {% Y1 y1、分类模型# ~) T) B5 k9 y7 N4 ^* z
主题:如何对分类模型进行评估5 g" ?/ m' ?2 C1 D/ H
目标:
+ ]6 v! s$ t! D' K2、混淆矩阵" g! ]# q$ B2 g8 h
3、评估指标
7 f3 m* n Y* ?" H' ?! R" Z5 r3.1 正确率7 y& Y9 }' Z% m8 \
3.2 精准率
/ P. i5 X5 Y! Y3.3 召回率) T! N) O: b7 E* L2 F' U
3.4 调和平均值F1
! B8 @7 R' N5 w2 X: \; Q% q# I4、ROC和AUC4 J/ U! u% R* \
4.1 ROC曲线
6 p8 e E& W' C! ?* c" o如何画ROC曲线:
4 v$ {1 V/ c% _0 i4.2 AUC
* K* W4 R' ^0 Z5 W4.3 ROC曲线程序示例8 u) T6 v& F6 p2 n/ H# W0 Q
4.3.1 roc_curve函数的参数3 i: i$ Q. `. L
4.3.2 roc_curve函数的返回值0 f/ L+ x$ H. g" o1 K) |
4.3.3 绘制ROC曲线1 f6 |; A( E) t. M
5、总结
; l* |: U2 @- x1 W4 C& k1、分类模型
4 P: l: t8 U: p, a/ l5 b) n% v1 J1 L: L
分类问题在我们日常生活中处处可见,比如我们对帅哥的分类,可能对帅哥分为非常帅和一般帅。比如我们平时刷淘宝,淘宝根据我们平时的喜好给我们推送产品,那我们就会把产品分为感兴趣和不感兴趣两类。
4 \& I& O1 n+ {$ I2 h2 N上述所说的问题就是典型的分类问题,确切的说其实就是二分类问题。
1 ]; V n# X2 Y1 e5 c能够解决这些二分类问题的数学模型就被称为二分类模型。9 x/ \5 G1 i/ `
用数学的方式表达就是,给定自变量X,代入到我们的分类模型F,会输出因变量y,y的取值为0或1,其中0代表负样本(一般帅的帅哥、不感兴趣的推送),1代表正样本(非常帅气的帅哥、感兴趣的推送)。- i% K5 x4 r( w8 k7 e6 Y
6 U5 l$ L( o$ }9 C, U主题:如何对分类模型进行评估/ c8 T' [$ [# ]$ @; s
) E2 h9 x" {% ^7 G% ^' i8 B2 r5 `7 ~目标:
D1 n! g/ ^# ~9 u4 z' d! `
6 d" C5 W, R! Y* X/ t- m1 Q! N能够熟知混淆矩阵的含义。
/ f. T# O. y& D3 f3 {7 t; L; o能够使用各种指标对分类模型进行评估。
/ o. O5 Y8 T' w7 T. h, G$ ^! O. ~能够独立绘制ROC曲线,并熟悉该曲线细节。" m# f3 L, A$ w+ u' w6 y
能够对样本不均衡进行处理(扩展内容)。* |4 {& f/ h" D2 F* F A9 P9 [+ }% l
2、混淆矩阵
% v7 b- O8 @* D! m V7 [2 O# z& ^
' H2 ^# h% f7 H6 ?混淆矩阵,可以用来评估模型分类的正确性。7 L5 K8 @3 u' |. a: L
该矩阵是一个方阵,矩阵的数值用来表示分类器预测的结果,包括真正例(True Positive),假正例(False Positive),真负例(True Negative),假负例(False Negative)。
2 `/ X5 w8 F$ e% b( ~ M8 N
- u$ ?0 f8 ?$ u3 [3 y
矩阵的形状是2 x 2,其中, - 矩阵的左上角表示,预测值为1,实际值为1(True Positive,简称TP); - 右上角表示预测值为1,实际值为0(False Positive,简称FP); - 左下角表示预测值为0,实际值为1(False Negative,简称FN); - 右下角表示预测值为0,实际值为0(True Negative,简称TN);
' u( D5 v6 n8 [. p# I
+ _- w% F# D" r- |3 w. H' O- T真负例(TN)+ 假正例(FP)——每个类别真实存在的负例的数量
4 E- n1 F" ~$ f& b( C/ u$ g: p& O$ `假负例(FN)+ 真正例(TP)——每个类别真实存在的正例的数量
8 x$ W7 j7 Z1 w0 j( H( A# A真负例(TN)+ 假负例(FN)——每个类别预测的真负例数量
6 [" O" t& e2 n* K" J. ?/ q% y假正例(FP)+ 真正例(TP)——每个类别预测的真正例数量+ W7 z+ b0 J/ Y; x |# z
其中:
' w: |9 r1 ~0 d& H! l
) t" L9 _+ @6 r& }# P5 JTP:真正例,实际为正预测为正;: n3 l3 z% W& f9 f, A$ u/ |
FP:假正例,实际为负但预测为正;
! v& |# l& c: n. p3 f# w9 f6 u1 tFN:假反例,实际为正但预测为负;) S8 y/ I: _" X. Q k. w; v
TN:真反例,实际为负预测为负) V/ v6 Y6 {* G/ h3 H2 a1 ^) o
接下来,我们通过数据来看下鸢尾花的混淆矩阵:7 B* |# a; J: z2 Y& V% {) N
import numpy as np
% U: K: y- m/ L/ |, wfrom sklearn.datasets import load_iris
# l7 u7 o4 {/ H: Y/ n* yfrom sklearn.linear_model import LogisticRegression
4 i. h- q' l1 J ofrom sklearn.model_selection import train_test_split
& u6 H+ ?4 i0 `' h! p3 x- c- N0 I# 混淆矩阵
; u' G& M" e0 ?& Vfrom sklearn.metrics import confusion_matrix* k. D/ k7 k; T
import matplotlib.pyplot as plt
9 b; ~. D) H( e3 T- O4 ?import warnings. U: K& P3 H2 |5 y( c/ X7 a" l
( D3 o& E) }+ ~; e3 ? C l8 }
plt.rcParams["font.family"] = "SimHei"
9 O! s) n0 C$ |. m( I/ c6 [* Wplt.rcParams["axes.unicode_minus"] = False
1 L8 ^1 N4 \/ o6 ?. g! K' L `plt.rcParams["font.size"] = 12
5 K, H) q; `- qwarnings.filterwarnings("ignore")
- _+ m" c$ k& p, q0 I
/ K$ [* q) Y3 [iris = load_iris() #导入鸢尾花数据集
6 j: y; b2 ]' R4 I" lX, y = iris.data, iris.target: S; a6 b. u; l" b% d+ w) n* l* H
X = X[y != 0, 2:]
. |7 ?, n9 v6 z- V/ ?* By = y[y != 0], ]2 X3 D" l, \, Z0 z8 T
y[y == 1] = 0
) s" Y* \$ O4 M! p0 ?6 ^y[y == 2] = 1
& i. A3 W- I- g' H$ |8 O/ zX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)0 [: e) i( a! k) B/ _
lr = LogisticRegression() #使用逻辑回归+ g1 q& Y( u- l# L& _
lr.fit(X_train, y_train)
/ F( G3 I4 h: y5 [: x- y. Uy_hat = lr.predict(X_test)
: ?! V1 k( W# w: {3 W3 H# 根据传入的真实值与预测值,创建混淆矩阵。: L7 U" U4 c, i d
matrix = confusion_matrix(y_true=y_test, y_pred=y_hat)# w% Y9 p4 x8 h
print(matrix)
' V4 L; |7 E; H. P! K1 _, i' E7 J& x+ c% A( h% s7 q3 x
; }3 C0 o3 F% D: V3 \% j' B输出结果:; n: {% @# ^) c( H
! Q4 S, Z% K2 F, U& q* G我们还可以对其进行可视化操作:$ D" i7 h8 p/ R3 [; }$ G- M
mat = plt.matshow(matrix, cmap=plt.cm.Blues, alpha=0.5) #cmap 指定颜色图色系,alpha透明度
& D6 U$ K# D$ q, [; q5 h1 elabel = ["负例", "正例"]
9 y3 l$ O {1 Iax = plt.gca()
H$ y+ j. @# W0 V; R$ f9 Bax.set(xticks=np.arange(matrix.shape[1]), yticks=np.arange(matrix.shape[0]),
7 e* a$ Q$ u4 m& J; v xticklabels=label, yticklabels=label, title="混淆矩阵可视化\n",
. F# V1 O" j- S7 P ^% r ylabel="真实值", xlabel="预测值")1 [: ^, A+ S$ C- {) X+ h( b) l
for i in range(matrix.shape[0]):
7 j# E4 z5 z5 V& H& D5 m for j in range(matrix.shape[1]):
0 _* y% x( K: r" R4 V W" C plt.text(x=j, y=i, s=matrix[i, j], va="center", ha="center"), i2 a& m/ N+ x. \3 o
a, b = ax.get_ylim()6 ?) H" Z3 i. u, a4 j! w5 \+ c
ax.set_ylim(a + 0.5, b - 0.5)( G4 c5 k2 }1 T
plt.show()
7 v& N% v8 A( |4 P
4 j: Q) U+ c4 t% z. {2 \- C- W2 ^2 N- ~1 Q
代码解析:' Y. g7 H: \5 ^5 J3 B
matshow( ) 绘制矩阵,alpha 透明度
; u" _& P$ X( j, H结果:
* a& P% ?, m8 i5 E+ d
! ?2 h; d) V; t: `5 ^: \9 N& L; w/ k/ U练习:# f# q; c+ i* V: o: ^
5 Z8 X! Y: Q, E" g2 K
关于混淆矩阵,说法正确的是( ABCD)。【不定项】
- d$ @# a. h# W1 U% q+ B- Z! JA 混淆矩阵可以用来评估分类模型。3 `" \2 j8 t8 E; m9 W- C9 M
B 混淆矩阵中,TP与TN的数值越大,则分类的效果越好。( C. K; t( z% n/ @ N3 n
C 混淆矩阵一行元素的和代表某个类别的实际数量。
7 s/ ? f9 _% J- m3 A! z4 L7 VD 混淆矩阵一列元素的和代表某个类别的预测数量。2 l* @/ T" _+ v/ p. l
3、评估指标
; I. g& k4 K- K& @; e) B- ?6 f# i$ \/ \: d
对于分类模型,我们可以提取如下的评估指标:0 S4 @- P) E/ X1 q+ ~, m4 k3 h
/ X& S& j4 E9 Z. q- ?$ W; D正确率(accuracy)
& U$ h, @3 c$ A* j精准率(precision)* R0 V4 O% D0 t
召回率(recall), q! d% O; E- s6 o9 A
F1(调和平均值)
- L3 n& E5 h, \* o4 L4 Y3.1 正确率
1 z j' B4 Y& p; \2 H g
3 L v: E) l. i正确率(准确率)定义如下:
. j& q; n4 H! T+ t U9 F1 A衡量所有样本被分类准确的比例。# O3 M- W [4 C' A
Accuracy = (TP+TN) / (TP+FP+TN+FN)
; ?* s, R c8 x+ T, x; [" t! c) K3 g6 E5 L: [9 ]2 a; x( k, Z
预测正确的数量除以总数量。
; W: \, r' H) a Q3 S3 a6 i# F3 s, e6 v" o. F/ W
3.2 精准率8 A9 p" p u; x: b b! |0 q8 i2 f, ]
& A' j* ]6 u" U- C9 M1 ^+ i查准率(精准率)定义如下:
* S* t% A) J7 |3 u; Z5 G C# L4 w9 B+ ]; G衡量正样本的分类准确率,就是说被预测为正样本的样本有多少是真的正样本。, z& K# W. i4 S9 K1 Y+ R
Precision = TP / (TP+FP)0 s" L% j* ^1 `. e% c9 A
2 Q$ U/ r$ O, w- D. n精准率只考虑正例。* S, C j1 P' i; }5 _6 d
9 o/ t) m g0 Z0 I/ e0 w
3.3 召回率% ?# ~( O1 v+ X+ `, X
7 u2 i$ T) ^$ _9 |/ R# y0 l& |查全率(召回率)定义如下:
! J/ J; U' i7 }& g表示分类正确的正样本占总的正样本的比例。
# t5 n6 Z) a$ Z+ Q6 H4 q' jRecall = TP / (TP+FN)5 X# m, h0 k0 e+ d
1 v' Q0 M0 d# @: Q4 `- J, C+ b# F o5 }4 O
3.4 调和平均值F1
! K. W3 P: D8 c8 x5 @
4 n7 i1 K/ j2 L/ U- w/ Q" ]
F值(F1-scores)调和平均值F1定义如下:; J; R; g z+ G( }7 _: t9 u- u
精确率和召回率的调和平均。
5 r/ h. E- M- y% O! F: D- u/ y' z, f精准率Precision和召回率Recall加权调和平均数,并假设两者一样重要。 D2 n2 ~' e- Y4 g2 \
' d' x& ~6 q- O/ x; j, z& G4 h" _F1-score = (2Recall*Precision) / (Recall + Precision)3 p* X# z7 \1 M: v3 f8 T$ V
a8 O! m/ l* p/ |9 D
精准率和召回率是一对矛盾的度量。一般来说,精准率高时,召回率往往偏低;而召回率高时,精准率往往偏低。通常只有在一些简单任务中,才可能使二者都很高。5 T) i( n* p8 p+ k! i% A' z7 ?$ H
最好的分类器当然是准确率、精确率,召回率都为1,但实际场景中几乎是不可能的,而且精确率和召回率往往会相互影响,一个高了另一个会有所下降,因此在实际应用中要根据具体需求做适当平衡。
7 Z+ t! Y7 C& y0 S8 V7 i让我们做个练习加深下印象吧!: n' X T ~4 F) |, |4 [0 \. B+ b
) T% q8 ~4 Y( b0 {/ }% z
以下说法正确的是( C )。! E/ U$ F, V! v. K8 s- i! ^- r- d
A 使用正确率去评估一个分类模型,效果会比精准率更好。
9 ~( [0 p; B' F. P) W4 rB 使用精准率去评估一个分类模型,效果会比召回率更好。
! X+ a0 P! ?$ l2 h0 dC 精准率与召回率通常要联合使用。" x/ M' x' g! Y* C% Z; ?$ F2 L& @8 I+ Q7 |
D 精准率与召回率如果有一个值较低,F1值也可能会较高。- [& z( y1 r! U6 Y. z/ e
如果精准率和召回率我们只能选择重视一个,我们会更看重( C )。4 G0 T$ {3 _; P: B" W1 p# R3 c$ t C
A 精准率。4 b. y, Q& n2 ^
B 召回率。
3 R$ G$ g: v' f( E* T6 zC 具体场景不同,重视谁也会不同。
3 P) o2 R' H' j4 {, w' f7 `接下来我们通过程序来说明下:
% u+ w* w1 t3 q: xfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score$ T4 p- ]6 c5 O5 {7 m+ F0 J& t
6 @7 [% E$ {. R% X
print("正确率:", accuracy_score(y_test, y_hat))/ L/ g% m, R( Z
# 默认将1类别视为正例,可以通过pos_label参数指定。
2 x, k2 l5 ?* p* Nprint("精准率:", precision_score(y_test, y_hat))
9 n! u$ \% e1 T( R# }print("召回率:", recall_score(y_test, y_hat))
6 \) A6 P, H, Uprint("F1调和平均值:", f1_score(y_test, y_hat))* D0 ~+ Z( p. z1 d i
# 我们也可以调用逻辑回归模型对象的score方法,也能获取正确率。
' n3 w) l* |' {8 ^) \$ r2 s# 但是需要注意,score方法与f1_score函数的参数是不同的。
2 N! Q& N% x3 U1 ]% aprint("score方法计算正确率:", lr.score(X_test, y_test))9 r9 e8 u9 Y, n2 n& Y) \1 r% l
+ @! p" p6 b* f f- p& D" y4 v. b4 t, S& C: A8 t
结果:
, v3 n z6 h7 I* m v E
' J. Z w/ S( R
除此之外,我们也可以使用classification_report函数来查看模型的分类统计信息,该方法会返回字符串类型,给出相关的分类指标评估值。
5 ]( o9 O7 w! v% u! r- pfrom sklearn.metrics import classification_report% {* F; i* U1 i E* M0 P
' k1 j( p; r/ p; T1 w' @+ U. c2 M {print(classification_report(y_true=y_test, y_pred=y_hat))& g f0 u2 a" }( W! y/ v" x# B6 r
& V+ V; @+ X6 x: F$ Z6 ?, |6 S
% W* H) j! T. b结果:) D2 f+ M) V W; V
) _+ c( `1 y7 B. E: L# M( c
) B. ?9 p8 C& d) J练习:
; F) F/ [" Q F6 V- M/ N
+ R( E0 Z$ h4 |; w/ Z$ V如果使用精准率与召回率评估二分类模型时,我们应该将哪个类别设置为正例? (B)) P Q! V5 ]2 ~2 a5 e
A 随意3 K$ I+ Z7 \- q) q/ b$ G/ P9 `. A0 I
B 关注的类别
9 C" h) @% v5 \$ q9 `0 `C 不关注的类别/ e" c" U# k% j) T
4、ROC和AUC* w. J3 g2 N. K
& M" P: p- h: D4 ?* dROC(Receiver Operating Characteristic)曲线和AUC常被用来评价一个二值分类器(binary classifier)的优劣。
& M* K: Y) `, ^5 o( n- o2 e" ?
- u% g' t. F3 e1 M2 i4.1 ROC曲线( U# O6 p0 l, O; d" k2 _0 R
. ^+ A2 p6 N$ u+ A, N4 j0 L. E. m/ sROC曲线(Receiver Operating Characteristic——受试者工作特征曲线),使用图形来描述二分类系统的性能表现。图形的纵轴为真正例率(TPR——True Positive Rate),横轴为假正例率(FPR——False Positive Rate)。其中,真正例率与假正例率定义为:
! X o9 E! b* M- G8 `% o* W1 u' v4 ~0 X& L
ROC曲线通过真正例率(TPR)与假正例率(FPR)两项指标,可以用来评估分类模型的性能。真正例率与假正例率可以通过移动分类模型的阈值而进行计算。随着阈值的改变,真正例率与假负例率也会随之发生改变,进而就可以在ROC曲线坐标上,形成多个点。4 w8 y8 [% N# _5 N0 H: s- }
9 ^ U0 |) V: ?$ C0 I5 n
ROC曲线反映了FPR与TPR之间权衡的情况,通俗来说,即在TPR随着FPR递增的情况下,谁增长得更快,快多少的问题。TPR增长得越快,曲线越往上凸,模型的分类性能就越好。
. u! z6 B2 W+ p F0 L
9 u" t: n) N. | OROC曲线如果为对角线,则可以理解为随机猜测。如果在对角线以下,则其性能比随机猜测还要差。如果ROC曲线真正例率为1,假正例率为0,即曲线为与构成的折线,则此时的分类器是最完美的。0 Q" W9 q) g+ E* L$ Z
) E- F& R: @9 Y& ~* \+ l
下图就是ROC曲线的一个示意图:. c" O+ t/ W* d, j3 q/ w
/ k1 U) ]: H/ P; r1 e
ROC曲线横坐标是FPR(False Positive Rate),纵坐标是TPR(True Positive Rate)
; ?5 C% y( D. O9 B9 h, O接下来我们考虑ROC曲线图中的四个点和一条线。4 W1 E2 q! }8 r3 G
\/ i7 @; V# ~第一个点,(0,1),即FPR=0, TPR=1,这意味着FN(false negative)=0,并且FP(false
3 L" w. k$ q3 ?5 c6 q% t; gpositive)=0。这是一个完美的分类器,它将所有的样本都正确分类。, Q# N( }3 Z+ D b
第二个点,(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。
. @/ a" J \' n& j. _9 s第三个点,(0,0),即FPR=TPR=0,即FP(false positive)=TP(true
* P8 [6 m0 }2 f; tpositive)=0,可以发现该分类器预测所有的样本都为负样本(negative)。
- T' G% E/ f0 f第四个点(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好。+ o$ J/ M* u0 y! m
如何画ROC曲线:
q! y6 w' _! o4 t; C( W- {
' k8 i. @6 f; s" d$ F7 z- @ k对于一个特定的分类器和测试数据集,显然只能得到一组FPR和TPR结果,而要得到一个曲线,我们实际上需要一系列FPR和TPR的值,这又是如何得到的呢?我们先来看一下wikipedia上对ROC曲线的定义:7 ^, Y# ^& Z# U8 Q/ `# ?! |8 z
! q$ F+ }& |$ v3 P* e9 L6 c
A receiver operating characteristic curve, i.e. ROC curve, is a
, G/ @( I, O0 J8 e- W+ Ographical plot that illustrates the diagnostic ability of a binary( w% ]5 G9 D) L+ }; `- j
classifier system as its discrimination threshold is varied.
: }( L& ^( ]% b: p8 c% l6 d译:ROC曲线是由一系列因区分阈值变化产生的点,用于描述二分类模型的判断能力
' k, R8 D* {' D" \, d这里的关键在于 “its discrimination threshold is varied” ,因为对于一个二分类模型,它的输出结果其实是判断这个样本属于正样本的概率值,假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变“discrimination threashold”?我们根据每个测试样本属于正样本的概率值从大到小排序。下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率! T& e: m3 t$ f- l5 y- V) U! I
9 }; w* u* d$ S6 ?# ^) c然后我们按照样本的score值,从大到小依次作为阈值,当样本score值大于等于阈值时则判定为正样本,否则为负样本。% T* C& g6 w; S
例如第一个阈值取0.9,这时只有id=1的样本被预测为正样本,其余都是负样本,此时TPR=1/1+9=0.1, FPR=0/0+10=0。还例如:对于图中的第4个样本,其“Score”值为0.6,那么样本1,2,3,4都被认为是正样本,因为它们的“Score”值都大于等于0.6,而其他样本则都认为是负样本。
- m- {7 v1 _3 b, w9 d
! l; v% J6 o- r/ a* x详细如下:$ `" L5 O0 t$ @3 ~/ b+ ]
" e3 f9 y# @& a @6 ?* Z" c( W由此我们便得到了一组(FPR,TPR)的值,可以绘制出ROC曲线:2 ~+ F6 \4 b2 K2 _/ i2 s
1 J m0 P: A* I2 |/ a
当我们将threshold设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。+ c$ z( ^: D) @& V
3 x* T/ T# u. T+ l7 w
4.2 AUC1 [1 V* r3 R9 R# t; t/ |
$ j1 s+ u: K6 ?AUC(Area Under the Curve)是指ROC曲线下的面积,使用AUC值作为评价标准是因为有时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而AUC作为数值可以直观的评价分类器的好坏,值越大越好。
1 }/ N) P: h) ~
7 _4 E k$ @! X9 `* j3 V: d3 Z! {AUC是ROC曲线下的面积。
* g4 h) y2 P* D0 Y* b! A3 D& @, XAUC的取值为[0.5-1],0.5对应于对角线的“随机猜测模型”。' ?, _" Y' U& V$ p; R
AUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前面,从而能够更好地分类。
! x, _( n$ |4 y. ^# z0 U5 ~7 d$ L# P
从AUC判断分类器(预测模型)优劣的标准:. g5 ]( F H7 |7 t) e/ B3 A$ z
* f, u/ o |% I& i7 C# @. _, o
9 ]$ F- a, Y& m7 \9 s7 K
例如一个模型的AUC是0.7,其含义可以理解为:给定一个正样本和一个负样本,在70%的情况下,模型对正样本的打分(概率)高于对负样本的打分。; k5 a% X- H1 E* G, k
3 P9 T% M/ s* Q5 N, }* |# [
三种AUC值示例:( M, q& D6 R# C; U
& B4 O( E: O6 C- h5 ]( `: g0 q简单说:AUC值越大的分类器,正确率越高。
" x2 c' T, {& y6 y) H' z* P
$ |9 Y1 H9 b/ a- m那么为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?
0 a/ h5 M) @. ~ v, G/ P因为机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。也就是说AUC越高说明阈值分割所能达到的准确率越高。+ C7 H7 T& }2 z4 _7 K2 ~4 _
% n; L9 H1 O( k% i. o
小练习:
6 \3 t+ D1 `' H, Y/ v7 J' O# |2 v
$ S0 A9 a0 n) N% X. \# o. {以下说法正确的是( ABD)。【不定项】! m3 M7 v3 }" R: ]4 |# v" W
A 随着阈值的降低,TPR与FPR都会增大。3 g, E8 h2 v) w+ L: @& ^: c8 \: _
B TPR与召回率的值是相同的。1 f& K8 Z# y& {& F( j
C 如果AUC的值非常低,例如,0.1,则该模型效果很差,也很难调优。1 w0 a8 W. b# n
D 无论是什么分类模型,ROC曲线一定会经过(0, 0)与(1,1)这两个点。
: t# P+ X! P5 e( v5 [, j3 F4.3 ROC曲线程序示例! }+ Z8 g6 ?( L' a% w
0 E+ m* K+ ^ T4 h我们首先来看一个简单的程序示例,借此来说明sklearn库中,ROC曲线的实现细节。
! D8 ?- V, D h n" R2 u% H1 Q% S5 n: H- X
4.3.1 roc_curve函数的参数' X; I5 F4 S D7 _3 n
import numpy as np
$ [ I/ `$ u$ ` X4 i+ T, A ?" ~from sklearn.metrics import roc_curve, auc, roc_auc_score
5 {1 `7 P1 k1 R' Ey = np.array([0, 0, 1, 1])* F6 ]( Y" R/ X `. T. `
scores = np.array([0.2, 0.4, 0.35, 0.8])% r+ S) o# A$ `7 |. c i9 e) v3 }
# 返回ROC曲线相关值。返回FPR,TPR与阈值。当分值达到阈值时,将样本判定为正类,
9 ~& D9 |9 ]! w9 `# 否则判定为负类。
5 d0 F) b5 J1 n1 N1 S# y_true:二分类的标签值(真实值)。+ b. S. ?+ q0 b$ `7 J n- k
# y_score:每个标签(数据)的分值或概率值。当该值达到阈值时,判定为正例,否则判定为负例。( g, s9 O* N7 z, I) i0 B, R
# 在实际模型评估时,该值往往通过决策函数(decision_function)或者概率函数(predict_proba)获得。+ R' |6 w' H2 K2 j, @ h7 P
# pos_label:指定正例的标签值。
% @7 Y" n5 ^6 J6 L& ]3 T5 gfpr, tpr, thresholds = roc_curve(y, scores, pos_label=1)
& F; X- z/ g3 U1 Iprint(f"fpr:{fpr}")( ]7 f* T5 L! ^- z, r9 c/ r& \) D
print(f"tpr:{tpr}")5 u# m' K) J4 N# R. c4 N4 ^) K& O0 P
print(f"thresholds:{thresholds}")' b4 {# \1 Y3 m% I0 x$ H
# auc与roc_auc_score函数都可以返回AUC面积值,但是注意,两个函数的参数是不同的。" H9 a, p$ n( J* f' a) u8 `
print("AUC面积值:", auc(fpr, tpr)). w6 o/ x \4 F
print("AUC面积得分:", roc_auc_score(y_true=y, y_score=scores)) }4 @! E8 O3 q, S
#### 3.3.2 roc_curve函数的返回值! o5 {! y8 i& U, A, N
' v' J6 E. R7 r: r# {; y6 f
结果:
3 @4 E1 v" r( Q) w
1.8 是怎么来的?
; l4 ]& H* I' }, o J1.8是阈值中最大值+1(0.8+1)得来的。为什么这么算?因为要使得最开始得到的所有阈值都不会超过这个值,才能过(0,0)和(1,1)这两个点。
) w+ g! Q _ s B! ^
6 _4 B; {2 X- f% z% E4 X4.3.2 roc_curve函数的返回值 b2 q, v- g3 L, V4 x* N
# ~3 o, l: Y9 z( s; k' R1 `2 Qroc_curve函数具有3个返回值:
) s7 c4 \0 @+ X+ a/ W* {; \/ Z- s7 T- W. n8 r/ n/ z8 w- ]4 d. U3 m
fpr 对应每个阈值(thresholds)下的fpr值。9 k( V' c' D, q8 Z2 z+ K
tpr 对应每个阈值(thresholds)下的tpr值。& D1 {( y' P4 d7 H
thresholds 阈值。( P2 w+ L1 l4 s& o1 O* P
roc_curve函数会从y_score参数中,选择部分元素作为阈值(选择哪些元素属于实现细节,会根据sklearn版本的不同,也可能会有所差异。),然后进行降序排列,作为roc_curve函数的第3个返回值(thresholds)。同时,根据thresholds中的每个元素(阈值),分别计算fpr与tpr。
; e. R6 Q" P" X6 }% R+ u5 Miris = load_iris()
6 }. I; [# A( S8 I; U, j# IX, y = iris.data, iris.target
q" D' ?* ^/ M7 y1 ?$ h) |* M% |X = X[y != 0, 2:]; E$ T& g$ a& R. |: `' C# }, ?9 K, D
y = y[y != 0]
; s3 T& b+ s/ S! D9 C, s+ G( cy[y == 1] = 0
* J$ L, D$ b4 r( W& X" Jy[y == 2] = 1
' n3 M2 Y8 B5 BX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,
% G' v8 m" e2 @" X1 Frandom_state=2)& ?" q6 D' \: C4 l+ E
# lr = LogisticRegression(multi_class="multinomial", solver="lbfgs")6 L& E- p' }$ Z3 Z# s2 X2 _
lr = LogisticRegression(multi_class="ovr", solver="liblinear")! W+ m) o& H f! \! `
lr.fit(X_train, y_train)
+ r- v; e+ X+ C- ?0 d9 Q# 使用概率来作为每个样本数据的分值。
/ |8 M/ j: Y r( ] P' A# qprobo = lr.predict_proba(X_test)
( i, l9 e" J/ T" \. Y8 l5 Jfpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=probo[:, 1],( o; @0 n4 ]$ i2 q: N: f, l. {
pos_label=1)
* U8 C% w; K5 j7 z6 Tdisplay(probo[:, 1])
2 a0 y: i3 B, W$ q/ u' `# 从概率中,选择若干元素作为阈值,每个阈值下,都可以确定一个tpr与fpr,
- e% M& k7 ~- o5 e9 T/ s# 每个tpr与fpr对应ROC曲线上的一个点,将这些点进行连接,就可以绘制ROC曲线。; @# h B* `9 J8 v( `4 o
display(thresholds)0 c5 g# t' K& @1 Y0 O4 \& Q
+ ?! i+ u: w. E* }; k4 P4 @结果:1 |4 ^2 D; a2 |' ?8 z
& E8 c5 u6 ?6 S. o; q, r5 r* l
$ ~- O" Q7 O. {7 @3 a$ ^% K! x
. X0 f4 d* P, w+ A7 \6 a
# 随着阈值的不断降低,fpr与tpr都在不断的增大。
; A! c$ e, A2 v; D. ^! P/ X$ ofpr, tpr
5 i/ |! i4 d# E- k1 |+ I" x& J( E4 i; J; C2 I
结果:! i0 B! h6 J, c5 {
$ \ e' o/ y9 W) r! l H
( z, H; l, q+ T C* l) Q" B4.3.3 绘制ROC曲线3 ]6 [6 Z& C: |3 N8 O" |4 z: u
有了fpr与tpr的值,绘制ROC曲线是非常容易的,只不过是最简单的一个plot而已。# f( F& x, h5 O( \/ S
plt.figure(figsize=(10, 6))
( }, e1 u8 h7 I2 j% Aplt.plot(fpr, tpr, marker="o", label="ROC曲线")
: {/ k7 q: q& `0 Q- Hplt.plot([0,1], [0,1], lw=2, ls="--", label="随机猜测")1 N$ D' ]) ]5 J' A- u0 s7 r
plt.plot([0, 0, 1], [0, 1, 1], lw=2, ls="-.", label="完美预测")
) {( Q" W. G' v$ d6 _7 D1 ~1 Y+ Gplt.xlim(-0.01, 1.02)
6 V( f3 r( ^3 b1 ]) p: n7 gplt.ylim(-0.01, 1.02)
/ c8 d& f( [$ Kplt.xticks(np.arange(0, 1.1, 0.1))# Q* r' F2 T3 }3 x; h
plt.yticks(np.arange(0, 1.1, 0.1))
% X7 r2 Q: y3 }( O% N! a1 K( Vplt.xlabel("False Positive Rate(FPR)")
9 M& A8 L$ Z- t- B6 m7 k- k3 \plt.ylabel("True Positive Rate(TPR)")7 \" Q( u- `8 a) c7 T, X# g
plt.grid(), V* X) i0 d2 C0 v8 P% x: J" P l( v
plt.title(f"ROC曲线-AUC值为{auc(fpr, tpr):.2f}")/ ]3 ?0 s) D& o; V( s
plt.legend()
1 ^' a' W. c E vplt.show()$ H( e: N1 I) F& c( o+ w" T
: W! C; ]6 Q$ Y/ c! g, K o
5 H4 r! y2 _# `5 n5、总结
( I5 a9 f E6 E: z& v
( y/ u2 B6 O0 t# p {) n混淆矩阵的含义。6 M Z. E8 e2 Q
正确率,精准率,召回率与调和平均值F1的含义。3 C5 {2 d$ {; A* v& z/ B# `2 C
ROC与AUC。% _7 ?% U" @8 t6 E% F: l' ]: ^/ J
2 |- K7 s C, n( e* z/ n( X+ X6 u参考资料:
. N& x, q0 s6 r5 [1、https://blog.csdn.net/zuolixiangfisher/article/details/81328297% ?2 L6 L# e8 I7 i A: i r5 i
2、https://www.jianshu.com/p/2feb00839154
: z _! M" [3 J4 F' A) k) j3、https://www.cnblogs.com/kamekin/p/9788730.html
5 s- ?* L" \" s7 P4、https://www.jianshu.com/p/c61ae11cc5f6# Q+ {& E! B. z; w- @1 ?, j
————————————————: k8 O/ _9 B# V6 K
版权声明:本文为CSDN博主「糖潮丽子~辣丽」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; e4 L S# y, ^6 D% p {5 J
原文链接:https://blog.csdn.net/qq_39783601/article/details/105600700
# P) \$ w2 _ |( W
: q9 S v6 j7 t( P$ S1 u) l; A4 V, B8 r( E( i( s8 C
|
zan
|