- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563411 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174246
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
& N! F w6 a* |: C. V- H
详细讲解分类模型评估分类模型评估4 S: \& t9 {% ~' `
) s& S, n7 k* z$ G5 @ v! \/ S: O1、分类模型8 M6 H! d2 G& V5 d
主题:如何对分类模型进行评估
1 \: X! |0 _$ j/ C目标:: T: r# @9 E, R+ j( w0 {
2、混淆矩阵0 C/ N5 M6 M2 Q6 s2 G$ Q* w
3、评估指标" V& ~ _% Q0 b5 M( `3 p
3.1 正确率
- \6 A# r" z( u. Z; U3.2 精准率
0 l: u2 F4 ?3 ~$ W V6 d& y: \3.3 召回率
0 z3 s! V1 z I! U3.4 调和平均值F1
% W0 t* v) z- m* n, n- n4、ROC和AUC# o: }+ v% F8 v1 R' O5 \
4.1 ROC曲线; A b) W0 u+ U3 H8 J% y! r
如何画ROC曲线:3 T# ? w/ n: }' C% o! r5 C2 T
4.2 AUC8 O W. `9 U& R' b+ q9 [9 r9 @
4.3 ROC曲线程序示例& `. D0 z4 q: H2 n# ]
4.3.1 roc_curve函数的参数
; e/ V! G4 G! ^! T! T" t7 n- v4.3.2 roc_curve函数的返回值7 ~/ `* ]- k' C+ F% O$ l7 ^5 {
4.3.3 绘制ROC曲线
# s2 Y s, w W0 Y5、总结
1 w a% _* s# w" I1、分类模型
" [6 V2 ^1 ?0 ^3 {2 a3 |3 m' D
" i1 R4 ^( N1 j) _# ~# p l# Q分类问题在我们日常生活中处处可见,比如我们对帅哥的分类,可能对帅哥分为非常帅和一般帅。比如我们平时刷淘宝,淘宝根据我们平时的喜好给我们推送产品,那我们就会把产品分为感兴趣和不感兴趣两类。& j* Q' S4 Y6 H5 i4 R
上述所说的问题就是典型的分类问题,确切的说其实就是二分类问题。
) O# k6 M/ p8 x! \5 \5 O' l+ G能够解决这些二分类问题的数学模型就被称为二分类模型。
+ {, l' K6 Q& r6 {2 p用数学的方式表达就是,给定自变量X,代入到我们的分类模型F,会输出因变量y,y的取值为0或1,其中0代表负样本(一般帅的帅哥、不感兴趣的推送),1代表正样本(非常帅气的帅哥、感兴趣的推送)。. `7 G# l+ {" M8 y8 ^
! y% J7 ?! s! M' H( K0 U7 B3 P/ _
主题:如何对分类模型进行评估
0 H# j6 P5 T0 w# J; Z% e4 ?6 C9 ~8 q/ P
目标:
* k+ W5 T$ E$ V" H x, x) t3 e* O$ \& n4 w3 b8 g. w3 }- } @* Q3 I( P0 Y
能够熟知混淆矩阵的含义。; y4 E: R, K# {6 G7 D( Z1 a
能够使用各种指标对分类模型进行评估。; S1 r; @/ F% w; }4 E$ S
能够独立绘制ROC曲线,并熟悉该曲线细节。
7 D/ Y R, i: `- P) c能够对样本不均衡进行处理(扩展内容)。" v3 j! x9 K) r: S/ Q- i/ d; I' ~
2、混淆矩阵6 V% }! p2 ^9 v4 I7 G
3 Q* S7 Q: C) B8 I+ N- D) M9 |) s6 {5 ]混淆矩阵,可以用来评估模型分类的正确性。
7 Y, U1 B5 S0 }# B q' {该矩阵是一个方阵,矩阵的数值用来表示分类器预测的结果,包括真正例(True Positive),假正例(False Positive),真负例(True Negative),假负例(False Negative)。! q6 E) v4 y# D6 E
9 Z9 @6 c _ l3 X4 r L
矩阵的形状是2 x 2,其中, - 矩阵的左上角表示,预测值为1,实际值为1(True Positive,简称TP); - 右上角表示预测值为1,实际值为0(False Positive,简称FP); - 左下角表示预测值为0,实际值为1(False Negative,简称FN); - 右下角表示预测值为0,实际值为0(True Negative,简称TN);
: z. o0 i; B* C0 O" Q/ t) l; r# E3 o
真负例(TN)+ 假正例(FP)——每个类别真实存在的负例的数量8 d; d1 G, U2 @ j
假负例(FN)+ 真正例(TP)——每个类别真实存在的正例的数量, }+ v% M. Y. g% _, \
真负例(TN)+ 假负例(FN)——每个类别预测的真负例数量- P9 @' ?, J* V1 E5 ~
假正例(FP)+ 真正例(TP)——每个类别预测的真正例数量9 F+ X& o9 [+ t9 a$ w" b
其中:
& f# D/ O0 v, B- L( @ n& S$ C1 }5 W' v& D! _5 c/ ?
TP:真正例,实际为正预测为正; N+ N% n1 z/ Y5 v
FP:假正例,实际为负但预测为正;7 k) K6 j6 @: e
FN:假反例,实际为正但预测为负;# Q% e' P) Z2 s5 V0 v
TN:真反例,实际为负预测为负
( t# A# _7 ?4 I7 a接下来,我们通过数据来看下鸢尾花的混淆矩阵:
+ H, V$ R1 C3 _+ r* Kimport numpy as np2 K, @6 H4 F- z1 A4 ?- _ X
from sklearn.datasets import load_iris
& S& @# k" A& A( R1 \from sklearn.linear_model import LogisticRegression
3 b* M# s, C! E1 M2 q2 h G1 @5 Y* ifrom sklearn.model_selection import train_test_split
: T( m+ t- v8 v/ l X# 混淆矩阵6 m/ ~) q* O) U8 Z7 n5 n3 T0 R$ v5 f
from sklearn.metrics import confusion_matrix* R! }9 R: ^0 d# ^2 |0 q3 g# V
import matplotlib.pyplot as plt3 Q }) \. G2 f
import warnings
. T- N( V6 s: z+ F' z/ g- Q9 G! X$ w) L
plt.rcParams["font.family"] = "SimHei"9 s. ?# C9 x+ x3 e9 c
plt.rcParams["axes.unicode_minus"] = False, i# f7 \- Z9 g) f
plt.rcParams["font.size"] = 12
) o$ h# t, L/ p% x0 T2 \" lwarnings.filterwarnings("ignore")- P0 j* K) W6 |2 O4 g T' k
8 Y3 _; N1 k) S: Jiris = load_iris() #导入鸢尾花数据集
I" ]( |4 {% SX, y = iris.data, iris.target
4 u: I" W9 i& @$ J8 wX = X[y != 0, 2:]9 H/ F7 ^. y' d
y = y[y != 0]
7 H5 G( } q; Q; `+ sy[y == 1] = 0+ _6 ?5 e& t9 s3 Y. U$ C
y[y == 2] = 1 V$ N) a1 Z* g3 N4 q
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)
0 L4 b( l; N4 D* W9 h0 H0 }3 w! ~lr = LogisticRegression() #使用逻辑回归
+ E! Q: s. `; n$ Ylr.fit(X_train, y_train)
9 Q( w. Q) y+ Sy_hat = lr.predict(X_test)
9 z6 O5 J/ I3 F% S# 根据传入的真实值与预测值,创建混淆矩阵。' _0 a0 w6 f7 ^* `+ G
matrix = confusion_matrix(y_true=y_test, y_pred=y_hat)9 f7 _/ x2 A$ @4 K: t; U2 A
print(matrix); P8 h% p+ d+ S
9 L! o; e0 c1 f$ j3 l" s X. P/ @
; O' S( [6 t: y3 ]0 M8 N输出结果:) r3 g _. E( ~% N& c* v" L" k% \
. T; k4 v* V9 {/ j/ \6 y+ \
我们还可以对其进行可视化操作:
% a) S3 Y0 s) i- v7 U1 emat = plt.matshow(matrix, cmap=plt.cm.Blues, alpha=0.5) #cmap 指定颜色图色系,alpha透明度
& q+ M/ o, o/ t6 g% }( q2 N# a D8 `label = ["负例", "正例"]
3 `3 c7 D1 [* X' Q' d, v! Lax = plt.gca()# y6 T$ u4 L2 c+ L: K* c! P4 g
ax.set(xticks=np.arange(matrix.shape[1]), yticks=np.arange(matrix.shape[0]),, o- D5 m3 p" I" Y ?, C3 C' Z9 M
xticklabels=label, yticklabels=label, title="混淆矩阵可视化\n",# \( ]" |, g; v, ?$ S
ylabel="真实值", xlabel="预测值")
`$ R, @, r! r4 R8 Ufor i in range(matrix.shape[0]):2 f F2 q5 [% N1 l" X% k
for j in range(matrix.shape[1]):
1 \" Y- T% k. T m( V$ {& v0 v( n plt.text(x=j, y=i, s=matrix[i, j], va="center", ha="center")% J. [9 H; m. [/ |
a, b = ax.get_ylim()) r$ L0 f+ d! N# O" T
ax.set_ylim(a + 0.5, b - 0.5)
4 o; |7 Y* ~3 U' lplt.show()8 d0 k) G8 T: j1 P) ?
- @7 U8 V/ G2 |0 v) s" c, t5 w( f$ k, B! X
代码解析:
0 G3 U! y- ]" f! y5 w! Nmatshow( ) 绘制矩阵,alpha 透明度
% O- X4 o# c- p s b7 R p结果:
0 v. v: G2 Y9 c1 N k3 |
0 O t7 o8 b5 O( X; K f
练习:5 X- ]5 `& w' Y; w- ^
8 X/ S/ C) j9 O: e9 L% r关于混淆矩阵,说法正确的是( ABCD)。【不定项】+ m6 z* M% F7 o6 @1 U
A 混淆矩阵可以用来评估分类模型。1 c5 L$ N; x, J4 e" b2 f
B 混淆矩阵中,TP与TN的数值越大,则分类的效果越好。# H6 A m' E, d
C 混淆矩阵一行元素的和代表某个类别的实际数量。5 O2 K! | Z4 N+ C
D 混淆矩阵一列元素的和代表某个类别的预测数量。
% g6 }' z- E8 ~$ R/ ^4 @3、评估指标
$ ?! @/ D1 w4 a V/ B" F
- x) R# I z4 J' ?% _+ y6 u对于分类模型,我们可以提取如下的评估指标:
% r$ u2 B2 Q6 H) a8 {* F) s+ M( [: W/ @2 f
正确率(accuracy)3 Y) G" s# |) \% [& v Y
精准率(precision)
- S- }% _' e# u召回率(recall); I$ R+ c; L7 t& d0 s6 d; m6 o
F1(调和平均值)
* `$ g) [0 o7 c4 Q/ g. n3.1 正确率2 \( e `8 T1 X( g1 d3 \" j
: E& P% F/ Z0 w5 o1 d
正确率(准确率)定义如下:
/ n7 p6 Y7 ]8 k" @3 F3 ~5 B9 l衡量所有样本被分类准确的比例。
& V7 P9 l7 R# C) H, vAccuracy = (TP+TN) / (TP+FP+TN+FN)
5 O3 N7 P. ?) J2 w w: k' B `1 x i4 G) h+ M" l" j
预测正确的数量除以总数量。
6 X$ y8 L+ _6 r: o. V! ~- m4 b# A+ N) _
6 c8 I2 s0 e/ ^1 C4 j1 F2 T3.2 精准率7 n* w5 |; T7 h
; m# J+ J; P+ Y9 H; ~查准率(精准率)定义如下:
; |0 m+ @3 u3 W& J* o* ?. `衡量正样本的分类准确率,就是说被预测为正样本的样本有多少是真的正样本。
$ M* H& Z6 F( ^" V& J1 mPrecision = TP / (TP+FP)
% [7 v% [6 @ s9 Y
* E8 b: f2 W' l9 k精准率只考虑正例。( \' [. w% \+ R8 {9 v! s. g
. }8 X1 T7 e. Z5 Q8 ]9 q+ |. V
3.3 召回率
7 E8 _4 y0 l9 s# Q# P( l; ]
3 e$ D) B8 M, j: L
查全率(召回率)定义如下:! K( Y* Q3 ~& @0 _
表示分类正确的正样本占总的正样本的比例。
& ]4 U+ s& w! f: ORecall = TP / (TP+FN); d) ]) V# M" H# c8 ?! @( m! y& F
+ ^6 Y/ j3 ^, m+ C+ o5 K
L p( T) O* c/ g1 D1 K O3.4 调和平均值F17 }4 |. h6 @& w
' t0 u! x1 S4 L! LF值(F1-scores)调和平均值F1定义如下: Q5 Y0 Q7 r- n
精确率和召回率的调和平均。: S9 ~/ c% \& d O
精准率Precision和召回率Recall加权调和平均数,并假设两者一样重要。3 U& H7 H% O8 N. C8 p6 N7 `. v! ?8 o
& D! z1 ?3 D. I& m9 j! C
F1-score = (2Recall*Precision) / (Recall + Precision), V0 ^+ ?8 C$ E% M+ x
4 f2 F1 X2 J9 u- d/ W$ {2 E. X精准率和召回率是一对矛盾的度量。一般来说,精准率高时,召回率往往偏低;而召回率高时,精准率往往偏低。通常只有在一些简单任务中,才可能使二者都很高。
! v5 B, ]& P" t! c" ?4 M% Y最好的分类器当然是准确率、精确率,召回率都为1,但实际场景中几乎是不可能的,而且精确率和召回率往往会相互影响,一个高了另一个会有所下降,因此在实际应用中要根据具体需求做适当平衡。
8 ~3 @6 J+ K* N' i- G- [; a# C让我们做个练习加深下印象吧!
1 @/ Y$ ^/ w8 W1 @6 @9 g$ p4 d# K- {. t
以下说法正确的是( C )。8 c& L% W! R. {" h W
A 使用正确率去评估一个分类模型,效果会比精准率更好。8 [% t* N/ n1 I3 ]
B 使用精准率去评估一个分类模型,效果会比召回率更好。 o% Y4 ~( {/ e5 _9 R) s3 c
C 精准率与召回率通常要联合使用。
9 A, \8 ?3 `! |/ b7 tD 精准率与召回率如果有一个值较低,F1值也可能会较高。
1 a& t0 q; ^7 l$ g8 ?1 [- [如果精准率和召回率我们只能选择重视一个,我们会更看重( C )。- }" g o2 ]1 F& G9 U
A 精准率。
$ q; R/ k! [! e4 lB 召回率。
% a, s: J7 @' SC 具体场景不同,重视谁也会不同。
- I. @. \5 n8 R/ H6 X接下来我们通过程序来说明下:: @% k, d2 p. f" L8 E x* j5 j# g
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score3 _: ~# D l( T; t: S6 P
& \1 |9 g2 H6 A# v# C0 I9 Cprint("正确率:", accuracy_score(y_test, y_hat)), ^- s) l1 u2 x! ?+ G% r& P
# 默认将1类别视为正例,可以通过pos_label参数指定。
: R( ~/ T$ [/ B3 j3 Wprint("精准率:", precision_score(y_test, y_hat))
9 a; `, i9 ~ P( wprint("召回率:", recall_score(y_test, y_hat))
: i: A+ M# ]6 ~7 mprint("F1调和平均值:", f1_score(y_test, y_hat)). q* [. L3 U% s1 d3 t8 i. n
# 我们也可以调用逻辑回归模型对象的score方法,也能获取正确率。, t& L! |0 p2 ]( \# W
# 但是需要注意,score方法与f1_score函数的参数是不同的。- K0 z! j1 A* k! h& V
print("score方法计算正确率:", lr.score(X_test, y_test)) E6 m6 G+ v! z; P
7 @4 {$ q3 u( e, `9 L2 V
0 B6 J; z+ ^% t1 O
结果:
) d: Y' a" a# N
* Z5 W7 b; x0 H7 `: I
除此之外,我们也可以使用classification_report函数来查看模型的分类统计信息,该方法会返回字符串类型,给出相关的分类指标评估值。4 g+ H, s: v( f, ~# F2 J7 B; ~
from sklearn.metrics import classification_report
; A; c5 t# Y! F1 f& p; }# J% e* b, Y U
print(classification_report(y_true=y_test, y_pred=y_hat))
; N' C' B/ u- j2 B0 R
/ h2 V. h) ]6 o' I9 Z8 E2 q2 }% Z: d4 F$ O* S. P" h
结果:0 [: G/ N+ \) D8 _ A
: e: W$ Y1 e7 t4 u4 ^7 t0 F% R, p
5 F/ G% p8 K1 y5 z" ^练习:7 [' _* Q2 e* w$ F" d
% E, c2 |# |# c* d/ a* I) n) ^如果使用精准率与召回率评估二分类模型时,我们应该将哪个类别设置为正例? (B)
7 k4 k* I( A2 VA 随意
- Q3 L# O; `" T2 \( y0 Q# s3 IB 关注的类别8 u4 x6 c$ p6 I4 L- y2 h! o
C 不关注的类别
2 n: G- P* ^1 E& u/ O/ X- N! ~ F4、ROC和AUC, i) {/ V2 l( E+ G1 \2 C {
4 @ w7 ~( b$ l7 cROC(Receiver Operating Characteristic)曲线和AUC常被用来评价一个二值分类器(binary classifier)的优劣。
# U9 L1 t, w5 T4 X: e5 W* q, {# h$ m& y* z* P# k# o& m
4.1 ROC曲线# T7 t \3 E7 R
1 C# y2 v( J9 @! G
ROC曲线(Receiver Operating Characteristic——受试者工作特征曲线),使用图形来描述二分类系统的性能表现。图形的纵轴为真正例率(TPR——True Positive Rate),横轴为假正例率(FPR——False Positive Rate)。其中,真正例率与假正例率定义为:
0 r' V0 J! r1 k( J' R4 v, R) ]7 M5 {( I( k1 ^
ROC曲线通过真正例率(TPR)与假正例率(FPR)两项指标,可以用来评估分类模型的性能。真正例率与假正例率可以通过移动分类模型的阈值而进行计算。随着阈值的改变,真正例率与假负例率也会随之发生改变,进而就可以在ROC曲线坐标上,形成多个点。
- G1 l( `2 y% g- W0 h8 m; j: v) ?0 j2 E2 x. p, S8 a- G3 @' [3 h
ROC曲线反映了FPR与TPR之间权衡的情况,通俗来说,即在TPR随着FPR递增的情况下,谁增长得更快,快多少的问题。TPR增长得越快,曲线越往上凸,模型的分类性能就越好。: b/ `$ y4 k$ N5 w/ j* A* D- o1 A
2 D" |7 E1 u9 {& k7 Y
ROC曲线如果为对角线,则可以理解为随机猜测。如果在对角线以下,则其性能比随机猜测还要差。如果ROC曲线真正例率为1,假正例率为0,即曲线为与构成的折线,则此时的分类器是最完美的。
; ~' y s0 H& N3 f* Y0 Y- P b$ _$ @8 p
下图就是ROC曲线的一个示意图:
6 y2 J! p S! _, l6 i
; q7 H; X+ y% }$ K6 q+ g4 T; WROC曲线横坐标是FPR(False Positive Rate),纵坐标是TPR(True Positive Rate)' t) a( A3 p( A
接下来我们考虑ROC曲线图中的四个点和一条线。
0 O; H" _' {$ q1 [" |# P" _& r! }$ D. T
第一个点,(0,1),即FPR=0, TPR=1,这意味着FN(false negative)=0,并且FP(false7 e/ s; B' K5 b4 J5 z7 D
positive)=0。这是一个完美的分类器,它将所有的样本都正确分类。$ a- r$ D- Z/ O# a
第二个点,(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。. b# @" J) L! }) H6 x
第三个点,(0,0),即FPR=TPR=0,即FP(false positive)=TP(true
0 [( h6 U" J$ zpositive)=0,可以发现该分类器预测所有的样本都为负样本(negative)。$ Z% h [, @3 J, K: _
第四个点(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好。
K6 r% y3 H8 {- s5 a如何画ROC曲线:
9 T8 c& F9 e/ p( D8 x$ \8 t. R0 B1 @' |: l
对于一个特定的分类器和测试数据集,显然只能得到一组FPR和TPR结果,而要得到一个曲线,我们实际上需要一系列FPR和TPR的值,这又是如何得到的呢?我们先来看一下wikipedia上对ROC曲线的定义:
' C/ Y" X& v& e9 o" v$ {" j0 y0 f; @# X0 f
A receiver operating characteristic curve, i.e. ROC curve, is a
% _ v% [1 ]4 a7 }graphical plot that illustrates the diagnostic ability of a binary ^3 N5 f. C! i; ]
classifier system as its discrimination threshold is varied.& T; k1 ^9 I. Y, f: U1 a$ N
译:ROC曲线是由一系列因区分阈值变化产生的点,用于描述二分类模型的判断能力
; |& b5 D" c8 P: R/ o- O这里的关键在于 “its discrimination threshold is varied” ,因为对于一个二分类模型,它的输出结果其实是判断这个样本属于正样本的概率值,假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变“discrimination threashold”?我们根据每个测试样本属于正样本的概率值从大到小排序。下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率9 \4 \$ |5 ^" T0 x
( k& C) P6 w) a* }* U! W
然后我们按照样本的score值,从大到小依次作为阈值,当样本score值大于等于阈值时则判定为正样本,否则为负样本。, d, |$ h2 d' N* H- Y/ J
例如第一个阈值取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,而其他样本则都认为是负样本。+ Y8 C3 [/ I# e7 H7 h: U! n( E& h
* m4 M' O' G2 I9 |7 m% j- G详细如下:2 V/ l) k" ^9 D9 |% [: h* K
) a4 m" X7 h) S# X- \
由此我们便得到了一组(FPR,TPR)的值,可以绘制出ROC曲线:" i# l8 P( |1 L6 L5 B
I: ~4 ^) b, z4 |# K) W- Y当我们将threshold设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。4 Z$ L/ h5 Q" P, i) X8 Y$ x) J
; J) q3 i) K; x# v* d4 U4.2 AUC
6 Q6 a/ _* o; l
- n2 B J! m- X- S' d
AUC(Area Under the Curve)是指ROC曲线下的面积,使用AUC值作为评价标准是因为有时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而AUC作为数值可以直观的评价分类器的好坏,值越大越好。
]5 i" f% k0 o6 B8 Y
$ e, m) v4 x- z# G6 `0 ]AUC是ROC曲线下的面积。( \' j* ^/ I% r3 X1 A: W; x9 U6 L; S
AUC的取值为[0.5-1],0.5对应于对角线的“随机猜测模型”。
4 c- F' @1 }, u4 YAUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前面,从而能够更好地分类。
$ q5 E0 @/ l3 f1 r3 p# V5 @
1 {0 x% b E m从AUC判断分类器(预测模型)优劣的标准:
. |# y0 F7 E- s( k! ?/ e3 p
8 z9 R4 @# b0 O+ B3 w
7 _: d& m3 J R1 i0 r例如一个模型的AUC是0.7,其含义可以理解为:给定一个正样本和一个负样本,在70%的情况下,模型对正样本的打分(概率)高于对负样本的打分。
( t) X. w0 y& R/ N
; p) n$ D) q# g三种AUC值示例:0 G: j4 [$ e7 h0 o+ [1 \9 r! Y
2 p, B" S: x2 u. t
简单说:AUC值越大的分类器,正确率越高。
9 `1 ?% z8 q6 z& y8 }/ U' z. d
那么为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?
7 d( _6 e+ A9 |! u因为机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。也就是说AUC越高说明阈值分割所能达到的准确率越高。7 Q0 ~ ?$ M5 s, D4 Y- u6 x
; U# W; S8 h/ F
小练习:
! w; g! o' M5 Q/ t b) i
+ G8 a) t; W3 s0 e6 s0 s# K0 p以下说法正确的是( ABD)。【不定项】) z. A3 N. f( O1 B& q* T
A 随着阈值的降低,TPR与FPR都会增大。 F/ `( b1 L, \# l
B TPR与召回率的值是相同的。
D+ S4 |' l7 N) CC 如果AUC的值非常低,例如,0.1,则该模型效果很差,也很难调优。8 S! Y+ [& ?5 H2 ?1 Y+ @
D 无论是什么分类模型,ROC曲线一定会经过(0, 0)与(1,1)这两个点。# C$ T8 i, j# A1 g. ~" L' }$ _
4.3 ROC曲线程序示例
9 m. b. Y& y7 w( }! u5 ]* N2 X: {0 b9 g7 f5 S6 a( P& s8 m) b
我们首先来看一个简单的程序示例,借此来说明sklearn库中,ROC曲线的实现细节。. [% J; \/ B- h
`1 A3 A3 Z# Q9 c3 ]& O
4.3.1 roc_curve函数的参数
6 D# Z0 I) E$ `$ A2 C; D: @import numpy as np& _) d/ q- i D2 P% [
from sklearn.metrics import roc_curve, auc, roc_auc_score
8 E5 X* y- |7 c. Y, G9 @ jy = np.array([0, 0, 1, 1])
W5 H9 [2 F d. ^: m$ H! _ Rscores = np.array([0.2, 0.4, 0.35, 0.8]), z) i" y/ H3 ~7 X( F
# 返回ROC曲线相关值。返回FPR,TPR与阈值。当分值达到阈值时,将样本判定为正类,+ M: a$ G! V8 R1 F* k# m
# 否则判定为负类。 _0 ~( L% E5 |- \1 E3 B
# y_true:二分类的标签值(真实值)。. H& f9 r" y$ e$ B
# y_score:每个标签(数据)的分值或概率值。当该值达到阈值时,判定为正例,否则判定为负例。
6 x# e: J3 `/ Z- f" q# 在实际模型评估时,该值往往通过决策函数(decision_function)或者概率函数(predict_proba)获得。 F) o7 l; [- s# M9 k! _
# pos_label:指定正例的标签值。. i3 O6 H1 X8 C
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=1)
1 S" t$ J3 v7 @8 U- S8 d0 Wprint(f"fpr:{fpr}")
& \5 Z: T% q @print(f"tpr:{tpr}")/ N8 D Y7 L+ i/ c" Q
print(f"thresholds:{thresholds}")- t$ @5 Y2 W3 R& f @
# auc与roc_auc_score函数都可以返回AUC面积值,但是注意,两个函数的参数是不同的。
: S2 W) i( W) ^) d$ N: kprint("AUC面积值:", auc(fpr, tpr))
+ v6 p. Q* \8 }print("AUC面积得分:", roc_auc_score(y_true=y, y_score=scores))
% B0 W7 P' X7 _% |: j) |#### 3.3.2 roc_curve函数的返回值+ t! C" U* S+ o+ V5 l
3 V# f. F: V. W/ R8 I! `' t# {结果:
, R c" p4 A7 r8 B
1.8 是怎么来的?* v" M) T5 e4 Z" @# L8 a
1.8是阈值中最大值+1(0.8+1)得来的。为什么这么算?因为要使得最开始得到的所有阈值都不会超过这个值,才能过(0,0)和(1,1)这两个点。/ A9 Q+ }1 Y& f. F4 o
4 [8 f @" H5 F5 f% M
4.3.2 roc_curve函数的返回值
' N0 V' H/ D! q2 X/ d9 {' e n
2 q" s U3 I- M _+ H* v7 ^roc_curve函数具有3个返回值:
0 e7 T5 B/ G, O& T3 J6 m/ g& r; w. O1 y' y! A/ t
fpr 对应每个阈值(thresholds)下的fpr值。+ h6 C \3 C% z% P* ]! ~( p
tpr 对应每个阈值(thresholds)下的tpr值。, x; H! T. x. I
thresholds 阈值。
8 f+ D/ {- W8 j2 T2 v; f+ hroc_curve函数会从y_score参数中,选择部分元素作为阈值(选择哪些元素属于实现细节,会根据sklearn版本的不同,也可能会有所差异。),然后进行降序排列,作为roc_curve函数的第3个返回值(thresholds)。同时,根据thresholds中的每个元素(阈值),分别计算fpr与tpr。% O5 y0 U6 ]% X2 y( ]9 M" X
iris = load_iris()7 q% H1 T6 E$ m
X, y = iris.data, iris.target/ j" t* F _4 D8 k. M$ q d3 k
X = X[y != 0, 2:]' x* g% |, v, M! a! J/ T+ U- b% y
y = y[y != 0]" ~, L# G4 j% @+ C; f; V
y[y == 1] = 0
" r/ k) V( k6 }. }9 By[y == 2] = 1
% O; s$ N3 ~" G0 u3 _X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,+ C) U5 ^' ]5 X6 ?0 d
random_state=2)) H b2 C3 d W8 {* o
# lr = LogisticRegression(multi_class="multinomial", solver="lbfgs")
, A l' v' \7 Ilr = LogisticRegression(multi_class="ovr", solver="liblinear")2 |+ k, u, u2 `! U2 o. r" h, z
lr.fit(X_train, y_train)
( [* O4 B+ E( i9 }; r* k' F& I# 使用概率来作为每个样本数据的分值。
5 }: F4 C" E" @4 G0 tprobo = lr.predict_proba(X_test)! Q" u4 E1 q% Y* A, {2 l
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=probo[:, 1],# r3 u, G) [1 s5 \+ F5 A' o! i
pos_label=1)1 \; K1 y6 m, o) A: n
display(probo[:, 1])$ q f) S% P2 v% i9 ~: P0 t. K5 y
# 从概率中,选择若干元素作为阈值,每个阈值下,都可以确定一个tpr与fpr,8 x0 J `1 N+ T; n/ P9 v5 Z5 {
# 每个tpr与fpr对应ROC曲线上的一个点,将这些点进行连接,就可以绘制ROC曲线。
4 N" Q9 P) l& c5 w, `display(thresholds)
: ~6 i8 B1 m5 |) g2 a8 c; Y1 m
5 A. i4 F- s% g结果:, B4 V4 X! m% C- P) f
! T z! r, ]9 n8 l q& @
- N* \9 K3 R7 }+ L
" s# W( F0 K3 F2 w# 随着阈值的不断降低,fpr与tpr都在不断的增大。
( D+ n' D% f3 Jfpr, tpr) W) M( O4 ? W/ f$ J+ R. K
9 E; |4 T5 V) @) O ?
结果:+ L/ [7 h; ^0 M# o1 L
- _5 f9 I( b3 M5 B; p* B
2 I( ]* D. ?) [3 J( i+ L4.3.3 绘制ROC曲线! n; W) S" s( M0 k( R# _
有了fpr与tpr的值,绘制ROC曲线是非常容易的,只不过是最简单的一个plot而已。* R2 n- n9 Q1 e7 I8 D. t
plt.figure(figsize=(10, 6))
, A5 h) K0 G; R. `* Hplt.plot(fpr, tpr, marker="o", label="ROC曲线")' t L# G" Q5 o8 W
plt.plot([0,1], [0,1], lw=2, ls="--", label="随机猜测")( B/ M) a1 V: \3 E F* u
plt.plot([0, 0, 1], [0, 1, 1], lw=2, ls="-.", label="完美预测")4 a* M. S: T0 h% W5 g
plt.xlim(-0.01, 1.02)4 Y& N& M' t2 D4 [
plt.ylim(-0.01, 1.02)* G6 w9 e9 d. {6 M3 W
plt.xticks(np.arange(0, 1.1, 0.1))
: w' ]1 [: w# ^) p1 [0 U( Fplt.yticks(np.arange(0, 1.1, 0.1))4 e% {( G$ i' O$ ]
plt.xlabel("False Positive Rate(FPR)")
. t* S) k8 r- Lplt.ylabel("True Positive Rate(TPR)")
. s# {% t. X5 L0 R# s5 A+ iplt.grid()
! d4 ^) I! M6 ]2 G/ S7 c0 Dplt.title(f"ROC曲线-AUC值为{auc(fpr, tpr):.2f}")9 D! ~% q B3 b, ~+ }
plt.legend()
- w* u! a$ {3 ?3 Mplt.show()
" ]7 m7 x/ S8 m
& _2 c- ?& V# _) w j( f( {
3 g2 _% c& b% ]% T$ l _5 c* I
5、总结' ~4 S! O3 W& F" H C- F9 s
/ j% @, c5 Z' p1 K3 Y% L" E8 v2 T
混淆矩阵的含义。+ ^5 d1 L# n. B; @
正确率,精准率,召回率与调和平均值F1的含义。/ T3 q/ g( M; t
ROC与AUC。
4 {3 }7 f& b- \; }' s4 g5 u( [# ~, C; y3 C
参考资料:
+ i/ q, ?! A5 M9 h0 E" [9 D1、https://blog.csdn.net/zuolixiangfisher/article/details/81328297
. `, T% b( }8 n7 U2、https://www.jianshu.com/p/2feb00839154$ B% F4 R/ ]6 |% o
3、https://www.cnblogs.com/kamekin/p/9788730.html% ^, m$ S% M+ G+ m9 O5 ?5 Y( I
4、https://www.jianshu.com/p/c61ae11cc5f6
( r+ [! P( p+ B: _————————————————6 [6 o5 A0 w# }! ?; D( L9 `
版权声明:本文为CSDN博主「糖潮丽子~辣丽」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。+ K( v. c6 H: R
原文链接:https://blog.csdn.net/qq_39783601/article/details/105600700
% M: |/ [: W/ T6 F$ I4 \. _4 \- l
7 Q9 e$ P' F- |* c
- p- O" e% t, O" Z4 d |
zan
|