- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566871 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175284
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
" d3 k% `' E0 n8 j# ~# i. A$ p
详细讲解分类模型评估分类模型评估
& n" M2 Y; R1 T8 V x0 q' p* L- P. ^5 t
1、分类模型* Q) u8 b6 M Y% V5 O9 K
主题:如何对分类模型进行评估3 g0 \1 C5 a. K. U
目标:
& v- ^& E% h* l: I, G2、混淆矩阵
0 o6 O) H2 r" r* Y/ n9 ^! O3、评估指标 e6 Z3 Z5 \! r+ g Q$ T
3.1 正确率
) ?0 K. g7 a! b# u$ `3.2 精准率
& S) O9 l1 P D8 \2 k3.3 召回率
* F$ h ]( n4 ?: H3.4 调和平均值F1
0 r3 m1 m5 l- s) i4、ROC和AUC( l2 n' [' B" J+ g v
4.1 ROC曲线
5 _3 K+ [$ E% B) ` j5 ?3 t1 m5 k如何画ROC曲线:6 r/ c4 i8 w8 l" G5 N
4.2 AUC
, u6 v& X( h. l- h( j5 E( F4.3 ROC曲线程序示例
o: R% Q4 T9 E4.3.1 roc_curve函数的参数
% p# Z4 ]9 J/ r# T5 M! {4.3.2 roc_curve函数的返回值
" q( l2 i3 k; V7 o2 u& |! M" p3 ]4.3.3 绘制ROC曲线8 c" y) i: h1 T, Z& O+ g
5、总结
O/ D: n* Q h1 A: [1、分类模型
6 B7 g8 z/ H& Q0 N/ m/ d7 Q* T. |% y4 A7 I% K3 u$ `
分类问题在我们日常生活中处处可见,比如我们对帅哥的分类,可能对帅哥分为非常帅和一般帅。比如我们平时刷淘宝,淘宝根据我们平时的喜好给我们推送产品,那我们就会把产品分为感兴趣和不感兴趣两类。
, G* L; |) |) I1 p! t0 {& b5 A! C% D% k上述所说的问题就是典型的分类问题,确切的说其实就是二分类问题。! z: ]& {2 u; C* N
能够解决这些二分类问题的数学模型就被称为二分类模型。
4 l$ ^) J) G1 y/ J5 c' K" X- @用数学的方式表达就是,给定自变量X,代入到我们的分类模型F,会输出因变量y,y的取值为0或1,其中0代表负样本(一般帅的帅哥、不感兴趣的推送),1代表正样本(非常帅气的帅哥、感兴趣的推送)。% k; c( B% b' W5 ?% T, e/ v/ g
$ U( k: ` g; a5 f" s主题:如何对分类模型进行评估5 r' L5 h! `6 r( m' j) F
$ S R; E! h0 K; h+ U目标:
* g! p: w0 s, |! k! Q
6 L( |7 c- x% t8 q" \3 l能够熟知混淆矩阵的含义。7 `$ k& x* f6 c/ s
能够使用各种指标对分类模型进行评估。7 A* ?$ ?7 q7 ~/ H7 u4 s3 ?
能够独立绘制ROC曲线,并熟悉该曲线细节。
) C# { h* o- @ h$ Q! C o4 m& I能够对样本不均衡进行处理(扩展内容)。& ?+ S f1 L# Z; l+ ]# R7 K
2、混淆矩阵* A5 M. t% c6 y' U
, C/ \' L3 v! u$ V6 |& N3 O0 C
混淆矩阵,可以用来评估模型分类的正确性。
8 z+ J4 |4 T$ q/ `$ r该矩阵是一个方阵,矩阵的数值用来表示分类器预测的结果,包括真正例(True Positive),假正例(False Positive),真负例(True Negative),假负例(False Negative)。
1 H) T# i1 G# k% L5 J& [: J
/ P7 u7 A8 p9 @, K ^
矩阵的形状是2 x 2,其中, - 矩阵的左上角表示,预测值为1,实际值为1(True Positive,简称TP); - 右上角表示预测值为1,实际值为0(False Positive,简称FP); - 左下角表示预测值为0,实际值为1(False Negative,简称FN); - 右下角表示预测值为0,实际值为0(True Negative,简称TN);3 U$ w2 m6 b6 J. m+ l# V
6 ~. m, f. H! F( G" ^8 ^真负例(TN)+ 假正例(FP)——每个类别真实存在的负例的数量
3 W& t# @+ ^5 {/ A/ t) s假负例(FN)+ 真正例(TP)——每个类别真实存在的正例的数量: W& ^) I8 X4 C) I7 s1 R+ @/ X
真负例(TN)+ 假负例(FN)——每个类别预测的真负例数量6 s( \6 @3 _2 O$ n2 ]
假正例(FP)+ 真正例(TP)——每个类别预测的真正例数量
" e- n4 }$ Y" x3 l! }其中:
6 M3 M) P' b1 \7 [8 M9 i( O
5 K( X: h$ b/ V6 X7 ^TP:真正例,实际为正预测为正;) W8 l. s9 b. Z5 ^; V$ d
FP:假正例,实际为负但预测为正;* {7 `; c9 K7 t
FN:假反例,实际为正但预测为负;
9 K! J6 u. x3 w0 b* J/ t4 x, lTN:真反例,实际为负预测为负
* A) }; X! |* ]. {# V! F% {* X: a接下来,我们通过数据来看下鸢尾花的混淆矩阵:
0 {8 n* b& I+ ^import numpy as np
7 c. F8 k1 l4 H. U5 jfrom sklearn.datasets import load_iris+ }' A6 K/ S0 r: E
from sklearn.linear_model import LogisticRegression0 @$ a- w1 @* k* r2 A
from sklearn.model_selection import train_test_split7 t# G6 b9 @* G) l
# 混淆矩阵* V& b7 V* K1 a( S9 V! J
from sklearn.metrics import confusion_matrix$ u% G' s! }$ X. V0 Z6 a
import matplotlib.pyplot as plt
! J" l( C0 [* c3 b5 M, I; A" timport warnings
* V( D1 R' E6 O9 }, n
# b! p4 y& o$ x0 Splt.rcParams["font.family"] = "SimHei"
$ S2 _/ `( }- a2 k) vplt.rcParams["axes.unicode_minus"] = False
( X! s$ G9 E: V0 K, dplt.rcParams["font.size"] = 12+ I( q; c( x5 v5 a* V" n" q3 L
warnings.filterwarnings("ignore")
; z/ u% |* W6 f3 k* Q7 M( J% @/ R3 N2 Y2 ~
iris = load_iris() #导入鸢尾花数据集
0 H; |% `0 I( z+ Z/ V9 r7 ZX, y = iris.data, iris.target
! ]3 Q; l/ h5 E; n8 OX = X[y != 0, 2:]
5 N4 ~( S; ^% @! i# ]1 uy = y[y != 0]
' K. `! @8 i# \8 B1 h2 H ^9 g1 z! fy[y == 1] = 0
% t& i2 p8 R; k% P( C+ Z! cy[y == 2] = 1
6 ~ |# m, | J% q7 f/ V4 [/ UX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)' S4 Q' M2 d" \
lr = LogisticRegression() #使用逻辑回归3 r# W9 H0 [9 D0 ~& U2 w
lr.fit(X_train, y_train)' c# v- Y {; H# P/ g
y_hat = lr.predict(X_test)# U. s. o; q5 ?: A8 f' a
# 根据传入的真实值与预测值,创建混淆矩阵。8 t& g! O7 o! u
matrix = confusion_matrix(y_true=y_test, y_pred=y_hat)( R9 f4 X$ i( F0 W
print(matrix)
5 Z5 X& v3 t: M- c$ M9 P' W' v* @0 G I4 o: h, i
1 D7 N7 x) u7 v5 _: P输出结果:
. F! b9 G" a; ~' i3 n+ P3 s$ S% u& q" q
) E, Y7 B; V0 G. t! Y9 @
我们还可以对其进行可视化操作:' p5 G; t0 G6 R) ?
mat = plt.matshow(matrix, cmap=plt.cm.Blues, alpha=0.5) #cmap 指定颜色图色系,alpha透明度
8 s2 x2 }' v2 @2 c/ \! Glabel = ["负例", "正例"]
8 {' S# l# T, ~" v$ j4 y$ n" zax = plt.gca()
" i' V! k4 l0 Kax.set(xticks=np.arange(matrix.shape[1]), yticks=np.arange(matrix.shape[0]),( J1 ?! w/ ? }4 h0 r
xticklabels=label, yticklabels=label, title="混淆矩阵可视化\n",
2 ~0 H% I. x- \( \. v ylabel="真实值", xlabel="预测值"), b5 M% E1 {0 @: x+ E9 J
for i in range(matrix.shape[0]):5 p0 t \' k1 C) G# \! M( m/ g
for j in range(matrix.shape[1]):+ y! O. g# D/ f" H# i
plt.text(x=j, y=i, s=matrix[i, j], va="center", ha="center")
+ _% b @: u( x' ua, b = ax.get_ylim()& a- p5 }; ]8 `/ ^) L5 s
ax.set_ylim(a + 0.5, b - 0.5)8 q5 ~0 X2 V. w* K. J D
plt.show()
5 [/ a* {# l7 Y. J" C) i2 x* P' v& Q4 z
4 L7 M+ I2 n. r# L6 a+ F( n# {代码解析:# U' h; @! Z, {! S
matshow( ) 绘制矩阵,alpha 透明度% W3 I! u/ ~$ X
结果:
n4 c$ c- [: _- v" z% w
+ W. z2 C- \+ x% K+ Z2 K: q. I练习:
J" `8 v4 ~: e; N4 r' p( G V+ ?; b7 x( i( r7 D( c! O" C
关于混淆矩阵,说法正确的是( ABCD)。【不定项】# N# B! X7 u8 w7 v9 {6 e" c
A 混淆矩阵可以用来评估分类模型。
3 | |# a+ v' m9 I/ {3 h( QB 混淆矩阵中,TP与TN的数值越大,则分类的效果越好。+ B+ i/ w: k& {$ x
C 混淆矩阵一行元素的和代表某个类别的实际数量。
3 ^/ V, g( R- }$ `0 DD 混淆矩阵一列元素的和代表某个类别的预测数量。
" ~- a, Y# e; a3、评估指标
0 \ b+ T6 D1 g9 |7 P& z8 ~
& h4 {+ [: M7 g& r对于分类模型,我们可以提取如下的评估指标:
& W$ \0 E* h H# J. X2 [4 Y' K3 Y
正确率(accuracy)
: D2 s% @$ J( V1 P% i精准率(precision)
. T, n6 ]4 g( j% f+ A1 l+ }召回率(recall)2 ~# H. H6 \3 Y2 g; Q
F1(调和平均值)
4 j: w7 w3 U: f4 p3.1 正确率: {, r- Q B% Z1 q7 n3 D- i
, E& \/ \# j6 A$ G Z' j正确率(准确率)定义如下:
7 `3 S: f/ _/ C$ C+ o) ~4 Z衡量所有样本被分类准确的比例。
" e6 R% w, b8 x) I }/ ]Accuracy = (TP+TN) / (TP+FP+TN+FN)6 B; C4 v# ~9 Y" n# _
/ |; l% o9 ?2 L2 X
预测正确的数量除以总数量。
7 N( j* P+ H" L( C5 J2 v* [7 V! d- K
3.2 精准率# M+ }3 U" `& c' R! }1 M5 b1 w
0 L* o( L% A+ b/ E3 h
查准率(精准率)定义如下:8 s7 l! d% s1 h0 C! c9 _; j( M) J% `
衡量正样本的分类准确率,就是说被预测为正样本的样本有多少是真的正样本。
# p/ P @3 }& n7 Q8 o b: o# _Precision = TP / (TP+FP)
) o# F P$ P/ I2 Q k3 M5 U( C( \7 C
精准率只考虑正例。9 ]2 f2 J& i: o3 K, \% t
% ^3 R4 ^$ X) x+ C4 Q( x8 r6 y
3.3 召回率
9 h" n; d- z% ]; X: H" Y
; a3 j* u7 g) i; V0 ^% v9 g4 Y查全率(召回率)定义如下:
2 k6 i: m' B( f2 R$ q4 n; ]) q( K表示分类正确的正样本占总的正样本的比例。. p- P2 t a! y7 s
Recall = TP / (TP+FN)
& }- J0 D) q' R" a* U9 _: g% @8 f/ K9 Q- _- n
; \) j; Z9 s* m+ L1 M2 O7 t, W6 I: Y
3.4 调和平均值F13 q+ G! L h( [
6 |1 v" J8 _; ^2 i K6 {- tF值(F1-scores)调和平均值F1定义如下:$ G4 K+ M' x4 w1 V5 Q* Z
精确率和召回率的调和平均。% i2 [ F9 b/ c0 k* A" C+ Q
精准率Precision和召回率Recall加权调和平均数,并假设两者一样重要。5 t) ^. b* I8 w
+ ?. K$ D n4 W; B' |+ o
F1-score = (2Recall*Precision) / (Recall + Precision)
' e+ V) n- ^8 a5 ]2 h
: H+ [1 w! H0 C; m精准率和召回率是一对矛盾的度量。一般来说,精准率高时,召回率往往偏低;而召回率高时,精准率往往偏低。通常只有在一些简单任务中,才可能使二者都很高。1 m" Q' x, r$ J+ i6 }& }' U
最好的分类器当然是准确率、精确率,召回率都为1,但实际场景中几乎是不可能的,而且精确率和召回率往往会相互影响,一个高了另一个会有所下降,因此在实际应用中要根据具体需求做适当平衡。& ]# c7 ]5 I8 k6 M8 @$ J9 M
让我们做个练习加深下印象吧!
' v: u1 W& X6 k% n3 b1 g& }1 f$ _- k5 O! i9 @# w
以下说法正确的是( C )。7 ^, {/ Z. O/ j& r# o Y) g; Y
A 使用正确率去评估一个分类模型,效果会比精准率更好。/ e2 w" D9 k' Y
B 使用精准率去评估一个分类模型,效果会比召回率更好。3 Z6 m0 z6 s2 [, \; ]
C 精准率与召回率通常要联合使用。7 ]) \0 w) O6 @: W2 h B& H# ^
D 精准率与召回率如果有一个值较低,F1值也可能会较高。
6 I7 m# y5 F/ ]7 }* a" n如果精准率和召回率我们只能选择重视一个,我们会更看重( C )。
5 s, X8 T/ n) y1 e, Y, L& D! qA 精准率。
$ n! |2 _& W% A! UB 召回率。. @2 j$ F! s" c6 a- q7 g' B# B6 x
C 具体场景不同,重视谁也会不同。
9 R- A- |, w# ~5 q e接下来我们通过程序来说明下:1 ?7 J6 @ u k; ]
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score; c5 X X; g: g+ n) v2 x
$ {0 J8 u7 l' P( T2 F1 y7 Z. L# r4 X
print("正确率:", accuracy_score(y_test, y_hat))
2 e4 @5 T, {; K f9 Z# 默认将1类别视为正例,可以通过pos_label参数指定。
, r& r5 C4 G7 Z- `; {/ \* Z7 yprint("精准率:", precision_score(y_test, y_hat))% p4 `8 n, f! u& T9 n
print("召回率:", recall_score(y_test, y_hat))
+ B1 G- ^. u6 U% n6 o! L! }5 B- Xprint("F1调和平均值:", f1_score(y_test, y_hat))8 ]( z$ M& o1 c, B
# 我们也可以调用逻辑回归模型对象的score方法,也能获取正确率。. c. Q8 }# q' e+ \" [2 K
# 但是需要注意,score方法与f1_score函数的参数是不同的。
: P+ G; ]% p' y) r( U9 ~print("score方法计算正确率:", lr.score(X_test, y_test))
+ ~: b) |& b t$ p; ?& x9 {1 O6 M8 j2 E0 Q
& Y: @& Q$ E( ?( u( b! E& y# [ z. d结果:
- Z8 n2 o# i0 n; T9 S' ?' l
" A2 b0 f6 I/ f$ x. T9 k除此之外,我们也可以使用classification_report函数来查看模型的分类统计信息,该方法会返回字符串类型,给出相关的分类指标评估值。* }" x5 _2 `0 B2 z/ D' K6 s; z7 ?
from sklearn.metrics import classification_report
& s6 r+ _* l0 h2 M+ A6 H7 `+ v5 M7 P; v' ?3 O
print(classification_report(y_true=y_test, y_pred=y_hat))/ R/ P% Y# [# S
/ {5 O3 w& _& T! v6 ?* p6 M# _ n$ ]
结果:
$ r0 ]9 d. Q: ^; G( h
) l# Y/ T1 h0 e* g
( J. k4 m0 |% E+ J/ |
练习:
+ Y6 F6 h/ d1 R" n! ?: A- @+ s6 ~+ t" u9 m9 ~1 w% f! I
如果使用精准率与召回率评估二分类模型时,我们应该将哪个类别设置为正例? (B)
+ L) r- P0 a4 G+ O, }( n- lA 随意
8 m2 d: \7 q h+ k/ H! i* lB 关注的类别
: @6 a/ j' v6 FC 不关注的类别6 h* [) q: }5 m. ~6 V! y6 A. B
4、ROC和AUC
0 h/ S' v( T! U* h+ `' d. ]
{ Q' F8 d! P- zROC(Receiver Operating Characteristic)曲线和AUC常被用来评价一个二值分类器(binary classifier)的优劣。, t, c+ `& x8 B$ c# E# d
7 T8 ^& n% i Q. ^
4.1 ROC曲线) e. G4 X8 R" A. p' ~) I0 `+ w
' W5 ?, G+ ^" t
ROC曲线(Receiver Operating Characteristic——受试者工作特征曲线),使用图形来描述二分类系统的性能表现。图形的纵轴为真正例率(TPR——True Positive Rate),横轴为假正例率(FPR——False Positive Rate)。其中,真正例率与假正例率定义为:
( ^, c7 D J6 J! S/ }+ U; H" r3 v1 m( C# U6 U: Z7 i
ROC曲线通过真正例率(TPR)与假正例率(FPR)两项指标,可以用来评估分类模型的性能。真正例率与假正例率可以通过移动分类模型的阈值而进行计算。随着阈值的改变,真正例率与假负例率也会随之发生改变,进而就可以在ROC曲线坐标上,形成多个点。' }6 C9 g. T- l" h! l6 Z% N ?
3 z1 Y, s5 q7 ]) l
ROC曲线反映了FPR与TPR之间权衡的情况,通俗来说,即在TPR随着FPR递增的情况下,谁增长得更快,快多少的问题。TPR增长得越快,曲线越往上凸,模型的分类性能就越好。! `) M1 F5 h' u) U
' a) b1 w' @9 K' r9 L8 nROC曲线如果为对角线,则可以理解为随机猜测。如果在对角线以下,则其性能比随机猜测还要差。如果ROC曲线真正例率为1,假正例率为0,即曲线为与构成的折线,则此时的分类器是最完美的。
# V. _7 u9 |* p+ @' z% k; w& F7 k4 [0 @ i Z0 o7 P
下图就是ROC曲线的一个示意图:; u6 a9 W f, ~8 p" G; N
& Y7 f. }6 W( A7 V' XROC曲线横坐标是FPR(False Positive Rate),纵坐标是TPR(True Positive Rate)
! O( o& x' e! S6 k接下来我们考虑ROC曲线图中的四个点和一条线。
. J4 M, T5 x- }7 M; \
! n9 U- m( d+ p+ [- U第一个点,(0,1),即FPR=0, TPR=1,这意味着FN(false negative)=0,并且FP(false+ i+ {* _' [2 U! k9 ~% I
positive)=0。这是一个完美的分类器,它将所有的样本都正确分类。
4 ^2 e& q! M* D: t+ x9 Y第二个点,(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。 O j& l' a2 t( I" u# L# c
第三个点,(0,0),即FPR=TPR=0,即FP(false positive)=TP(true
, j1 Y8 y! W8 M( R2 ~positive)=0,可以发现该分类器预测所有的样本都为负样本(negative)。$ @" U( S5 E4 G7 F1 Z
第四个点(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好。; p( N: z- T+ v
如何画ROC曲线:) F6 o: z% l6 _6 O& R
6 G# M: @- q7 p( `6 X( y$ R7 z
对于一个特定的分类器和测试数据集,显然只能得到一组FPR和TPR结果,而要得到一个曲线,我们实际上需要一系列FPR和TPR的值,这又是如何得到的呢?我们先来看一下wikipedia上对ROC曲线的定义:& k- t- e$ Y, Y5 @! X5 f, m
+ p- W3 p) U8 D& b
A receiver operating characteristic curve, i.e. ROC curve, is a
+ e! e! N% D4 d' j8 X4 ~" Pgraphical plot that illustrates the diagnostic ability of a binary2 D: `' l4 u. R) `% Q& S4 B. ^
classifier system as its discrimination threshold is varied.: h' J# x, {4 ~! t1 A5 Q
译:ROC曲线是由一系列因区分阈值变化产生的点,用于描述二分类模型的判断能力" u0 m: T$ G; |4 D' f
这里的关键在于 “its discrimination threshold is varied” ,因为对于一个二分类模型,它的输出结果其实是判断这个样本属于正样本的概率值,假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变“discrimination threashold”?我们根据每个测试样本属于正样本的概率值从大到小排序。下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率& X3 N- o$ V4 w8 |2 [3 F
( e4 k% p* f5 P e
然后我们按照样本的score值,从大到小依次作为阈值,当样本score值大于等于阈值时则判定为正样本,否则为负样本。$ ^ H$ l, v7 Q1 N) l2 \1 x* M
例如第一个阈值取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,而其他样本则都认为是负样本。1 _3 w% K' {. x3 i$ o! G( H
1 S+ l- {( _0 I1 G6 d
详细如下:
& b4 _1 P- Z1 k' A
6 v! K' |" i3 m1 z
由此我们便得到了一组(FPR,TPR)的值,可以绘制出ROC曲线:4 a* C( L- D; [5 ~& r1 s9 H
& G3 w& N8 c' |) A+ ]+ l$ O
当我们将threshold设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。
, ]9 K9 N5 A, c, N
& F; V7 F) `; }9 h; s5 l7 D4.2 AUC
4 g4 n2 F: M8 J- v
% u0 `& w Q' T! }7 `2 G
AUC(Area Under the Curve)是指ROC曲线下的面积,使用AUC值作为评价标准是因为有时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而AUC作为数值可以直观的评价分类器的好坏,值越大越好。
7 S0 f8 R% O7 i$ j$ [0 u
* M J6 B! \+ s2 {AUC是ROC曲线下的面积。
: K8 r2 j! P! E: P! `! mAUC的取值为[0.5-1],0.5对应于对角线的“随机猜测模型”。' A7 i- A$ C2 e, w) R5 {
AUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前面,从而能够更好地分类。
/ i. s# ]6 F4 N" o2 `, O: c: D3 J! ?" w$ i) J( x) E4 ?5 g" ]
从AUC判断分类器(预测模型)优劣的标准:
7 |& f9 Z; C l, h5 g9 S
% q u1 a$ G9 c, [- P2 S6 [5 \1 m }. n7 i6 r, z, @' |& [2 s( R
例如一个模型的AUC是0.7,其含义可以理解为:给定一个正样本和一个负样本,在70%的情况下,模型对正样本的打分(概率)高于对负样本的打分。
2 C6 g, G0 u! \2 z9 L N8 ]) ~$ c Q
三种AUC值示例:* r- A9 z0 y: m7 X! {8 T
( u& E. s; X9 }/ K简单说:AUC值越大的分类器,正确率越高。% A, k' j+ W( X
2 q9 e- ]$ K' D [% A; t那么为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?$ S/ L& G5 ~9 W
因为机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。也就是说AUC越高说明阈值分割所能达到的准确率越高。6 h3 L9 `9 d, }. W6 _9 U* K
( V" F4 J+ [4 N
小练习:! o( k% @3 g0 ?) B
3 w1 O! ]" ?8 R( g
以下说法正确的是( ABD)。【不定项】
7 }, P* I" E7 Y9 j6 w8 ]A 随着阈值的降低,TPR与FPR都会增大。, |; {! [! ]2 ~1 r9 U/ S# h
B TPR与召回率的值是相同的。) v# L7 I5 X; u5 L% D
C 如果AUC的值非常低,例如,0.1,则该模型效果很差,也很难调优。" J) I7 `9 j# Y5 k2 h' d
D 无论是什么分类模型,ROC曲线一定会经过(0, 0)与(1,1)这两个点。# c5 r& O0 @9 e7 {
4.3 ROC曲线程序示例
- N/ _7 U9 }, y8 \/ V* O3 a6 O
& r* j8 F! D; s" z我们首先来看一个简单的程序示例,借此来说明sklearn库中,ROC曲线的实现细节。
* b9 x! Z) H6 k7 U3 n4 Q9 C
- p y0 I4 u9 y* H( l, ]9 J4.3.1 roc_curve函数的参数$ {+ Q0 E0 P* N/ y0 F; e
import numpy as np
: T9 v9 ]0 }: \" I2 G/ H- Sfrom sklearn.metrics import roc_curve, auc, roc_auc_score, d1 l6 G+ J X" x; \
y = np.array([0, 0, 1, 1])
* _! n' \( G; Y- h% j5 E1 s, lscores = np.array([0.2, 0.4, 0.35, 0.8])6 w+ f6 n' }( n( M2 S
# 返回ROC曲线相关值。返回FPR,TPR与阈值。当分值达到阈值时,将样本判定为正类,& W1 z4 P2 W9 e& ]
# 否则判定为负类。
6 d3 w' L) Z8 b# t" d1 D7 q \2 K# y_true:二分类的标签值(真实值)。& r1 Y2 C8 e' K: K. s1 Y
# y_score:每个标签(数据)的分值或概率值。当该值达到阈值时,判定为正例,否则判定为负例。
1 W: ^. E! S" U) l8 ? v$ O) Y# 在实际模型评估时,该值往往通过决策函数(decision_function)或者概率函数(predict_proba)获得。
0 O# c# Y6 Q& Z8 {! m7 {2 B# pos_label:指定正例的标签值。
$ ~- ~, E, g9 W, l) H& [fpr, tpr, thresholds = roc_curve(y, scores, pos_label=1)
" O0 |$ l/ g0 A- Eprint(f"fpr:{fpr}")
' N7 k' F* ]# e; N# m4 uprint(f"tpr:{tpr}")
3 _6 z7 w- C3 C0 zprint(f"thresholds:{thresholds}")
4 j4 ^# S! |; M5 ]# auc与roc_auc_score函数都可以返回AUC面积值,但是注意,两个函数的参数是不同的。
* ^. U/ X) d0 ~2 r& O" q) w7 bprint("AUC面积值:", auc(fpr, tpr))! w) z8 i+ c9 i. M0 v1 |
print("AUC面积得分:", roc_auc_score(y_true=y, y_score=scores)), C) N. s1 A" y
#### 3.3.2 roc_curve函数的返回值
, s7 ` w3 y# f( h8 w/ Z; `6 g+ S3 @
结果:
8 U% r/ M* l& _$ W5 O* f) D( Y
1.8 是怎么来的?
+ Z" o6 q. d3 ~- Z& y- w! J1.8是阈值中最大值+1(0.8+1)得来的。为什么这么算?因为要使得最开始得到的所有阈值都不会超过这个值,才能过(0,0)和(1,1)这两个点。+ i1 W) D9 k7 ~# S/ R# O3 Z/ N
9 S7 e6 A7 ]( ?* j) |' O
4.3.2 roc_curve函数的返回值
& D' L7 t1 Q# [6 l* K
. L+ Y, C8 l# broc_curve函数具有3个返回值:
1 E; J! z6 g) Z S; K( L1 R6 F4 N0 U& ], u; c, a9 e# v. g! M
fpr 对应每个阈值(thresholds)下的fpr值。) U; S8 f( E6 a2 u. x
tpr 对应每个阈值(thresholds)下的tpr值。9 {. j$ z4 L7 b) ?, ^, a" I3 F
thresholds 阈值。
- z3 o5 V9 y! U2 t( ?+ qroc_curve函数会从y_score参数中,选择部分元素作为阈值(选择哪些元素属于实现细节,会根据sklearn版本的不同,也可能会有所差异。),然后进行降序排列,作为roc_curve函数的第3个返回值(thresholds)。同时,根据thresholds中的每个元素(阈值),分别计算fpr与tpr。
# c8 i) D* i0 D5 J3 ciris = load_iris(): i7 D3 V8 a) i8 P- W7 f, A$ M
X, y = iris.data, iris.target. d; l) e2 j9 J" `
X = X[y != 0, 2:]
! L1 C4 z% C3 j; Oy = y[y != 0]# N+ t2 k4 {( w5 F( S8 D8 r
y[y == 1] = 0
# M4 @2 b. G W3 E2 V5 R' Gy[y == 2] = 1/ X6 D; N! ~5 X! T
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,: ?7 ^- b& M. D
random_state=2)8 u# j- R: B# B8 Y
# lr = LogisticRegression(multi_class="multinomial", solver="lbfgs")8 Q- l' L+ h. b3 N
lr = LogisticRegression(multi_class="ovr", solver="liblinear")# I8 e+ c0 c5 v5 Y; [
lr.fit(X_train, y_train). y2 n1 l8 i' S; x: w" G8 x5 M
# 使用概率来作为每个样本数据的分值。
- }( J; ?! L. x! Q( k/ j( kprobo = lr.predict_proba(X_test)7 m! s/ @, h; p; l+ ^. B
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=probo[:, 1],
$ A: c- t( w1 H- L8 kpos_label=1)
% R: J2 \( r# ^3 W( W2 W& ndisplay(probo[:, 1])3 Z v2 [6 M; a6 ^$ i
# 从概率中,选择若干元素作为阈值,每个阈值下,都可以确定一个tpr与fpr,
- N/ W7 q. y: T+ k: r/ q$ z4 X. d# 每个tpr与fpr对应ROC曲线上的一个点,将这些点进行连接,就可以绘制ROC曲线。
9 z% @( ?" e V" Kdisplay(thresholds)
2 M( t% |& n! [' [- [* ? F
6 Y9 ?. Y$ n, M7 W结果:
+ d: o/ Z+ q: Z: u; O2 l
( b8 _' o8 N) j1 [
; V6 ~* y3 C# g& Z/ O) w) @& [3 Z1 x' @; J$ {7 x" \# m
# 随着阈值的不断降低,fpr与tpr都在不断的增大。
; ]6 c, ?" r7 {; Ffpr, tpr
- h6 E& x4 y$ i+ h
# X0 b4 U+ Q1 d结果:" k5 I, E$ b4 T/ ]7 M. u1 z* o" G8 w
) n7 a3 O' r* E- L
* l0 n& C0 _& l, R4.3.3 绘制ROC曲线6 R! ^! W( ?! j* y3 O! z9 _
有了fpr与tpr的值,绘制ROC曲线是非常容易的,只不过是最简单的一个plot而已。
) V. A a8 l: w4 }. cplt.figure(figsize=(10, 6)); u! J8 n3 x# V2 o8 z2 | w
plt.plot(fpr, tpr, marker="o", label="ROC曲线")
9 c( g- S4 D4 e3 e$ oplt.plot([0,1], [0,1], lw=2, ls="--", label="随机猜测")! i4 g/ w+ m# p
plt.plot([0, 0, 1], [0, 1, 1], lw=2, ls="-.", label="完美预测")8 [5 c0 _$ G, j
plt.xlim(-0.01, 1.02)
3 j8 V% _/ U3 kplt.ylim(-0.01, 1.02)7 x# F n, h: G8 e. u# j
plt.xticks(np.arange(0, 1.1, 0.1))2 Q+ a, B( Z) w: x+ h7 i4 d4 T% q
plt.yticks(np.arange(0, 1.1, 0.1))
9 i% z+ ?7 P, x3 X3 x2 Uplt.xlabel("False Positive Rate(FPR)")5 P# J" F- E; t0 f2 s' |
plt.ylabel("True Positive Rate(TPR)")
$ |- E, N t1 d/ Z7 xplt.grid()2 [' N) A! U% g6 _ M
plt.title(f"ROC曲线-AUC值为{auc(fpr, tpr):.2f}")4 f: {2 C" u6 s. _9 d6 g
plt.legend()/ F: K( K7 B B. x* A' B
plt.show()' J' W0 t/ Q2 U9 @* B2 ]
, H( H( _3 {6 d8 a+ ~* s! @- N. r
* U1 K' u! {7 Y3 i4 c
5、总结7 F, J7 E* \* L: a* ~9 i- F
$ n) [/ D- T8 q. s3 x7 S混淆矩阵的含义。
8 L+ L, {) Y9 T& i3 W( f正确率,精准率,召回率与调和平均值F1的含义。
2 V) k- Z5 s: p! ^+ j0 T" kROC与AUC。$ m7 W) z0 a( Y) f; n+ y+ k
- \# |' O# e8 c+ t/ Y参考资料:: F( c n. K. t2 H
1、https://blog.csdn.net/zuolixiangfisher/article/details/81328297
" u6 {. I: o& D: q" w! L2、https://www.jianshu.com/p/2feb00839154
# K$ y, N/ \. o; _0 w! `5 ^3、https://www.cnblogs.com/kamekin/p/9788730.html& P* P# e* d; S& ~5 _
4、https://www.jianshu.com/p/c61ae11cc5f6/ }6 U: q- v' ], ~1 _' w+ v
————————————————
" m4 }. t6 {& s0 K( j, N版权声明:本文为CSDN博主「糖潮丽子~辣丽」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
! z7 U% `: r; T, ^原文链接:https://blog.csdn.net/qq_39783601/article/details/105600700
& b4 K0 w; L- b( ?
' {. f! c; e( L, X& [7 ?; X; k8 n7 N; Q
|
zan
|