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