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