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