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