数学建模社区-数学中国
标题:
详细讲解分类模型评估
[打印本页]
作者:
杨利霞
时间:
2020-4-19 11:53
标题:
详细讲解分类模型评估
# o0 t2 @7 Z2 [& c( @0 I0 ?
详细讲解分类模型评估
分类模型评估
6 H- w- _; q9 Z0 Y) l2 m
# p# O4 @8 b5 B2 ~6 X
1、分类模型
% n& y& A+ Q" m3 b+ {! n
主题:如何对分类模型进行评估
) D2 U, x# x) J5 B0 Y X: d
目标:
( D0 W) x [7 G/ z$ J
2、混淆矩阵
. Z% f& B, A$ [ q1 p9 x3 e6 {
3、评估指标
/ a2 \4 \0 d X, T# x
3.1 正确率
' J1 K- l+ F6 L( ?
3.2 精准率
" @( T$ g k3 F* E6 G
3.3 召回率
" [7 f0 i5 e( v6 i+ F2 h- W
3.4 调和平均值F1
; _/ I ?# b1 T* S7 T
4、ROC和AUC
! R- ~$ H# V) ^
4.1 ROC曲线
2 n# @! i! W* c/ l! p
如何画ROC曲线:
" U/ {1 G& Y" z6 R9 ^1 C. N
4.2 AUC
0 V! s1 J" s2 \% Y( c! T$ Y
4.3 ROC曲线程序示例
* a. o8 A8 x7 j0 G( I, u
4.3.1 roc_curve函数的参数
3 B3 Y7 C4 t3 h
4.3.2 roc_curve函数的返回值
& g0 V, Z6 N2 \- E, { e
4.3.3 绘制ROC曲线
: c8 C `5 U3 j q3 {' p( t
5、总结
) O# T" o- @& g" d5 P
1、分类模型
, S; C( Q K( y- O6 ^
# c2 `& f- m/ H2 ^0 M# u
分类问题在我们日常生活中处处可见,比如我们对帅哥的分类,可能对帅哥分为非常帅和一般帅。比如我们平时刷淘宝,淘宝根据我们平时的喜好给我们推送产品,那我们就会把产品分为感兴趣和不感兴趣两类。
8 o3 L" T% M: W
上述所说的问题就是典型的分类问题,确切的说其实就是二分类问题。
! K) d+ z9 [9 i( C! u
能够解决这些二分类问题的数学模型就被称为二分类模型。
/ I0 a3 m" |/ [# l! y
用数学的方式表达就是,给定自变量X,代入到我们的分类模型F,会输出因变量y,y的取值为0或1,其中0代表负样本(一般帅的帅哥、不感兴趣的推送),1代表正样本(非常帅气的帅哥、感兴趣的推送)。
^( c' r, H6 ^1 T7 v- h* W' r: |
G* _+ O9 ~3 m6 F* z! `. e0 W
主题:如何对分类模型进行评估
( i3 j6 O% K* S) `
5 R- U% e. f- R& v/ c
目标:
9 N4 d' a! R- R( Q* H
2 v$ [- e% G- t; h
能够熟知混淆矩阵的含义。
& w+ X2 \1 |( \! a8 W
能够使用各种指标对分类模型进行评估。
2 t% o( D2 w) T0 J3 \& ~3 @7 ~
能够独立绘制ROC曲线,并熟悉该曲线细节。
2 T C( Z7 _5 {/ C5 u
能够对样本不均衡进行处理(扩展内容)。
, C- |& q! m+ C
2、混淆矩阵
& E6 M3 r+ ] D! u' V& m3 v
/ V8 E4 u! O) Z1 c7 B3 t& a
混淆矩阵,可以用来评估模型分类的正确性。
6 _( R" {7 ~2 G. k5 i. V- i; h
该矩阵是一个方阵,矩阵的数值用来表示分类器预测的结果,包括真正例(True Positive),假正例(False Positive),真负例(True Negative),假负例(False Negative)。
5 m u& W8 S$ o" K! s9 H: O$ m- r
2020-4-19 11:42 上传
下载附件
(67.71 KB)
6 D, N5 a& a: ]) P
矩阵的形状是2 x 2,其中, - 矩阵的左上角表示,预测值为1,实际值为1(True Positive,简称TP); - 右上角表示预测值为1,实际值为0(False Positive,简称FP); - 左下角表示预测值为0,实际值为1(False Negative,简称FN); - 右下角表示预测值为0,实际值为0(True Negative,简称TN);
8 \0 V/ `# A& G) y
1 m8 E7 X& K$ f
真负例(TN)+ 假正例(FP)——每个类别真实存在的负例的数量
% @- [! {6 _ B/ Z+ f- a) R
假负例(FN)+ 真正例(TP)——每个类别真实存在的正例的数量
6 `* W: N# r' u; C; J& g: Q, G
真负例(TN)+ 假负例(FN)——每个类别预测的真负例数量
& |, Z$ S+ I3 N) f$ _7 |9 K
假正例(FP)+ 真正例(TP)——每个类别预测的真正例数量
( X" ^ b4 g- s: f9 X& t
其中:
+ s$ W! s \5 f
' U2 X+ }2 i: s0 H
TP:真正例,实际为正预测为正;
5 L3 \/ a- k% F& V/ C ~
FP:假正例,实际为负但预测为正;
+ H n! q x! C$ n
FN:假反例,实际为正但预测为负;
- m" X) w# ]; E' A' H' y
TN:真反例,实际为负预测为负
+ d2 q% V: z1 h; @2 F4 o: c
接下来,我们通过数据来看下鸢尾花的混淆矩阵:
( C9 t3 ^# A( n& p2 ~# A3 }
import numpy as np
7 q% e u& Z- b) v# N r
from sklearn.datasets import load_iris
0 t) ?% d) e- A9 l2 z/ N. l' R
from sklearn.linear_model import LogisticRegression
1 b& s; u+ P5 m$ ]2 q: I* H1 N3 c
from sklearn.model_selection import train_test_split
8 E/ n/ O- x. B4 F/ D
# 混淆矩阵
3 W% i/ W# [# h" v
from sklearn.metrics import confusion_matrix
3 O' n7 b( A5 T R9 ?
import matplotlib.pyplot as plt
" `; z! f6 `. {! Q$ l$ L6 H
import warnings
1 j- l8 k# B0 w! \/ g7 N+ F7 a
- \- q; f+ ~* x O* l1 S) f
plt.rcParams["font.family"] = "SimHei"
7 m( g/ @4 u' ?, I' v- W. r) B. ]
plt.rcParams["axes.unicode_minus"] = False
. A$ x- O) |# i8 ?2 P" }
plt.rcParams["font.size"] = 12
- W7 u1 L$ G8 ~" d' D4 V
warnings.filterwarnings("ignore")
! ~5 _% V3 K' X% t5 t2 d
: V. P2 u5 z/ G& b+ s3 ~ `5 ^
iris = load_iris() #导入鸢尾花数据集
/ O$ d0 ^# `. A4 o& G( m1 A
X, y = iris.data, iris.target
3 d, b' u! k" L& N6 E; ]- ~
X = X[y != 0, 2:]
6 s8 c/ L: u8 q1 r$ E) m
y = y[y != 0]
' A: s+ N' ?1 e- m J l
y[y == 1] = 0
6 T$ w$ n! j k- F+ j4 A
y[y == 2] = 1
1 L) o$ D& o* R* O# C% F( i" i
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)
& d: d" n- w1 N o" w3 E
lr = LogisticRegression() #使用逻辑回归
1 t! |3 Z* y6 S1 I
lr.fit(X_train, y_train)
, ^! {3 L8 {) F
y_hat = lr.predict(X_test)
u% u- x! f) n* @- L
# 根据传入的真实值与预测值,创建混淆矩阵。
, a( D' y% Y: o2 t: J( m$ R
matrix = confusion_matrix(y_true=y_test, y_pred=y_hat)
_; y7 w5 l8 m: e" g7 h
print(matrix)
2 W" m2 o* B, K3 U4 H+ H* d
% j) M. q7 Y5 K% w
( D: {# a7 a% R+ i' D( I3 {% t c
输出结果:
1 K3 B( A) R; W% o/ `
2020-4-19 11:42 上传
下载附件
(12.51 KB)
4 T8 v/ L/ b$ w( |
我们还可以对其进行可视化操作:
# R% G: R. X% W7 d7 E
mat = plt.matshow(matrix, cmap=plt.cm.Blues, alpha=0.5) #cmap 指定颜色图色系,alpha透明度
/ F! t0 Y) W2 L
label = ["负例", "正例"]
& N* ~" j7 o% ^& B$ Q! r1 S5 Z
ax = plt.gca()
) H) Y. @6 u* O: {( T3 q9 t% A
ax.set(xticks=np.arange(matrix.shape[1]), yticks=np.arange(matrix.shape[0]),
# g, [0 U0 L o8 s, k; e
xticklabels=label, yticklabels=label, title="混淆矩阵可视化\n",
2 r' G! Y2 z: i7 d4 W+ k
ylabel="真实值", xlabel="预测值")
|. j3 `( a |8 k; [$ F5 |
for i in range(matrix.shape[0]):
0 D% G( y* ?, r
for j in range(matrix.shape[1]):
k6 P) d5 z/ E1 G
plt.text(x=j, y=i, s=matrix[i, j], va="center", ha="center")
: y- R/ J( j, S
a, b = ax.get_ylim()
8 o, v0 p0 I! }' G
ax.set_ylim(a + 0.5, b - 0.5)
) I e" Z6 y' j8 m1 d: w. y4 e
plt.show()
+ V: Z8 S; f3 `
! M3 F! z$ e/ i7 g! i5 d
( n* d% w, n( q' w
代码解析:
' R# ]& ~& f+ M0 B
matshow( ) 绘制矩阵,alpha 透明度
0 U' ]6 j1 G5 h7 {! A# n
结果:
7 \' {+ f1 T* G* [9 _
2020-4-19 11:42 上传
下载附件
(7.85 KB)
* E3 G) Z Z6 ?# `' w# V
练习:
* B; P; u/ s8 W) @: A
) M! w* i; L' L+ N7 C* \
关于混淆矩阵,说法正确的是( ABCD)。【不定项】
- K& g1 {7 ?# a
A 混淆矩阵可以用来评估分类模型。
" B# r3 [9 q; c; i
B 混淆矩阵中,TP与TN的数值越大,则分类的效果越好。
+ B% Z/ v+ O% x6 F
C 混淆矩阵一行元素的和代表某个类别的实际数量。
3 \! i! q+ N0 {8 Y, H! J
D 混淆矩阵一列元素的和代表某个类别的预测数量。
. e* l3 J5 {# b. Y% b
3、评估指标
8 L% x; r+ K9 ~
0 j$ w' g4 q4 X) [( b: @5 O
对于分类模型,我们可以提取如下的评估指标:
) d% t! E$ W8 K, l
6 q: p5 }% j9 u+ r% x. J' |6 k
正确率(accuracy)
' b' @# ], b% k. F( l0 I% C" j
精准率(precision)
1 h+ o3 d- S; ^# Y# N
召回率(recall)
% ~4 M8 v5 m) q) B5 f% P) E
F1(调和平均值)
: }+ I$ ]3 [) g, U- N% F% e2 @: w2 }
3.1 正确率
) `( j& I ^2 {8 C7 I6 E
2020-4-19 11:43 上传
下载附件
(17.27 KB)
! n9 ^& ^8 }; a
正确率(准确率)定义如下:
2 p) Z- V7 }& Z" w& V3 w( _6 n- @
衡量所有样本被分类准确的比例。
2 v; r$ k: J0 v0 g0 s3 m7 { T* t
Accuracy = (TP+TN) / (TP+FP+TN+FN)
2 Q) h1 y: g7 w) m2 X( k, b9 z
! v" M3 D K' Q
预测正确的数量除以总数量。
% O! l4 ?3 U8 O- Y) J4 a3 e
* o: Q, i" K7 |- j0 \% o
3.2 精准率
: V4 P' l+ Z3 A' C; o
2020-4-19 11:43 上传
下载附件
(12.31 KB)
3 ^& g$ s% k, b0 Y" r
查准率(精准率)定义如下:
( C6 w8 b+ [7 {$ f9 f/ z+ b
衡量正样本的分类准确率,就是说被预测为正样本的样本有多少是真的正样本。
) G5 I2 r3 b4 f6 @
Precision = TP / (TP+FP)
6 [+ w& f. o) N9 f% u/ \/ l2 G
5 q% }2 F* ` T4 m) B$ b/ F# b
精准率只考虑正例。
/ ^7 v, P4 Z# G# ^' z$ T- Y k; z
- J9 Y7 U2 d" O$ g4 ^
3.3 召回率
0 c& R2 c: @- T$ D. U( a
2020-4-19 11:44 上传
下载附件
(10.08 KB)
" N+ Y! H, ?5 W7 l: F( `( ]: g+ S* `% F
查全率(召回率)定义如下:
2 d6 T: r, s/ `& `
表示分类正确的正样本占总的正样本的比例。
9 A2 C. f |/ }6 d) Y
Recall = TP / (TP+FN)
1 I. c& Q4 T1 \* O
! a. g5 Q5 M5 P; h
! r1 `7 ^3 ~# W6 Z$ o
3.4 调和平均值F1
X+ O& P, i% X v/ c% l
2020-4-19 11:44 上传
下载附件
(22.94 KB)
7 Z( V7 |1 h# E, u' E
F值(F1-scores)调和平均值F1定义如下:
( o E5 w8 F3 ]: m R& _& `& r9 u: @
精确率和召回率的调和平均。
, g( e& Q6 ]# ?/ U* G. N
精准率Precision和召回率Recall加权调和平均数,并假设两者一样重要。
4 ]5 X) V# Y X# L$ h U+ h
( j- z, t, x0 _5 N9 X- D
F1-score = (2Recall*Precision) / (Recall + Precision)
3 B* k- y9 u0 o5 }2 E j
! I/ c4 q! }& N: F. A1 _, ]) @
精准率和召回率是一对矛盾的度量。一般来说,精准率高时,召回率往往偏低;而召回率高时,精准率往往偏低。通常只有在一些简单任务中,才可能使二者都很高。
$ C5 |; {) |5 V8 u: Q
最好的分类器当然是准确率、精确率,召回率都为1,但实际场景中几乎是不可能的,而且精确率和召回率往往会相互影响,一个高了另一个会有所下降,因此在实际应用中要根据具体需求做适当平衡。
( s0 @4 i) e8 |% _" k0 C
让我们做个练习加深下印象吧!
' k. k$ k0 b7 |+ M S# O" W
l5 j @6 v8 C
以下说法正确的是( C )。
! F6 F; z: C' O0 p+ r9 X! e
A 使用正确率去评估一个分类模型,效果会比精准率更好。
9 L d1 X! m5 L4 x' j3 W# {2 U
B 使用精准率去评估一个分类模型,效果会比召回率更好。
0 h/ p# T3 |! k" `) f
C 精准率与召回率通常要联合使用。
- }, N+ [# b# h5 i
D 精准率与召回率如果有一个值较低,F1值也可能会较高。
& r6 _3 p7 V2 l9 l2 k7 K O. n
如果精准率和召回率我们只能选择重视一个,我们会更看重( C )。
6 W! o% {" K) i3 O, w, U I
A 精准率。
- g0 F/ v* C% r# r& g( @
B 召回率。
& ^9 n" h0 }/ F1 u$ L
C 具体场景不同,重视谁也会不同。
1 Y$ Q a1 W9 x j9 j5 w' a9 f
接下来我们通过程序来说明下:
! ~! [$ G) l- w" J7 O/ G
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
6 X5 f" \ r2 J9 l' P
0 g( t3 A" K6 n. h- q
print("正确率:", accuracy_score(y_test, y_hat))
. o) e& H; j+ d5 p( |/ b z8 v
# 默认将1类别视为正例,可以通过pos_label参数指定。
; w3 n1 A0 J. s
print("精准率:", precision_score(y_test, y_hat))
* W* r2 Z( W/ M- }- ?7 Q
print("召回率:", recall_score(y_test, y_hat))
5 S! ~, _2 ]7 N3 D m$ W- i
print("F1调和平均值:", f1_score(y_test, y_hat))
' E3 F. ^5 ]( B6 S U6 z5 ^
# 我们也可以调用逻辑回归模型对象的score方法,也能获取正确率。
) k5 u0 d1 M9 A) p# M
# 但是需要注意,score方法与f1_score函数的参数是不同的。
. z+ d' w( m z" Y5 t
print("score方法计算正确率:", lr.score(X_test, y_test))
7 q" d% O f9 g) r+ }
9 i, |' z( k# C$ a' x' x: Z( C
8 g: q/ _8 ^! y* L! [6 e9 u
结果:
7 y+ n* O$ m/ S/ p: n
2020-4-19 11:44 上传
下载附件
(5.55 KB)
2 e$ b/ |" H) T& i
除此之外,我们也可以使用classification_report函数来查看模型的分类统计信息,该方法会返回字符串类型,给出相关的分类指标评估值。
8 C4 g: ~. T' B
from sklearn.metrics import classification_report
3 R8 i. N: {$ T: ~2 N6 @ m
4 b7 G: [$ p! ]- Z
print(classification_report(y_true=y_test, y_pred=y_hat))
1 i, |+ @& w5 g& {7 d- I
, @3 f& S( q% X3 v( `% E. s! R
) _, w8 j% |7 i
结果:
5 e4 d% o& f0 m2 l5 E& R3 [. u
2020-4-19 11:45 上传
下载附件
(142.24 KB)
- P& u' A) ~ k- ?. b
: {7 W# K8 Q( H7 t e h
练习:
0 v: e; Z9 c. D( v" j- X) i6 V# n
0 i' N2 O+ A& W
如果使用精准率与召回率评估二分类模型时,我们应该将哪个类别设置为正例? (B)
, L1 G: X4 t$ C( ?! Q/ o
A 随意
5 c6 X" S( ^( `5 n3 }
B 关注的类别
4 h [' y+ ?$ h* D2 A( l
C 不关注的类别
3 a& n( X9 g }9 C' p1 Y
4、ROC和AUC
$ `& R) ?- T; L6 T- } B: i
' n y! }9 e5 ~9 ?! y" {
ROC(Receiver Operating Characteristic)曲线和AUC常被用来评价一个二值分类器(binary classifier)的优劣。
& {7 s' a( ]8 u$ X( p: i. T7 Z- p' I7 R
6 \. w4 x6 {6 ~7 l5 k
4.1 ROC曲线
4 ^: R" G) ^5 S3 B* L$ g
2020-4-19 11:46 上传
下载附件
(40.24 KB)
: B9 w% h* ~5 s' l
ROC曲线(Receiver Operating Characteristic——受试者工作特征曲线),使用图形来描述二分类系统的性能表现。图形的纵轴为真正例率(TPR——True Positive Rate),横轴为假正例率(FPR——False Positive Rate)。其中,真正例率与假正例率定义为:
7 c7 E& Q. ^7 v/ @( ^6 i) R
2 D3 I' ~5 }& k0 }2 A- w8 O ^) Z
ROC曲线通过真正例率(TPR)与假正例率(FPR)两项指标,可以用来评估分类模型的性能。真正例率与假正例率可以通过移动分类模型的阈值而进行计算。随着阈值的改变,真正例率与假负例率也会随之发生改变,进而就可以在ROC曲线坐标上,形成多个点。
- ~/ m6 O. s1 `( s5 f7 ?/ |
! v, l0 |/ p( Y6 I' s9 c, `
ROC曲线反映了FPR与TPR之间权衡的情况,通俗来说,即在TPR随着FPR递增的情况下,谁增长得更快,快多少的问题。TPR增长得越快,曲线越往上凸,模型的分类性能就越好。
, z0 Q1 q* ]4 ~* o
6 a5 f% z: J( f) Q
ROC曲线如果为对角线,则可以理解为随机猜测。如果在对角线以下,则其性能比随机猜测还要差。如果ROC曲线真正例率为1,假正例率为0,即曲线为与构成的折线,则此时的分类器是最完美的。
2 Q1 r( _" W& s+ ]5 _% G
1 A" |* W' n; }5 W' U) L: U
下图就是ROC曲线的一个示意图:
' _4 n& q+ _( s
2020-4-19 11:47 上传
下载附件
(73.81 KB)
5 J0 ?& m3 V5 k5 F' T0 n r
ROC曲线横坐标是FPR(False Positive Rate),纵坐标是TPR(True Positive Rate)
6 H3 ?/ O( \8 I$ E- s
接下来我们考虑ROC曲线图中的四个点和一条线。
, H' I9 m0 Y& p3 i: _ e
2 R% v3 f5 H6 Y3 M
第一个点,(0,1),即FPR=0, TPR=1,这意味着FN(false negative)=0,并且FP(false
3 S- C. D" U* E1 N% D) e6 {
positive)=0。这是一个完美的分类器,它将所有的样本都正确分类。
1 b! a7 u7 V" e D7 [: f2 P
第二个点,(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。
. v& a& X3 ?' k
第三个点,(0,0),即FPR=TPR=0,即FP(false positive)=TP(true
) M: b- L& K. g
positive)=0,可以发现该分类器预测所有的样本都为负样本(negative)。
0 w! _6 s/ f+ I5 H) g
第四个点(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好。
$ a# f$ D/ ~: N0 ]. L/ |0 v
如何画ROC曲线:
" s. x/ |: `7 W
3 K; L" S& r: C3 u/ e4 U% D
对于一个特定的分类器和测试数据集,显然只能得到一组FPR和TPR结果,而要得到一个曲线,我们实际上需要一系列FPR和TPR的值,这又是如何得到的呢?我们先来看一下wikipedia上对ROC曲线的定义:
4 D- Q" j3 ]0 `! _
- m% H8 S& |6 `. {" d d
A receiver operating characteristic curve, i.e. ROC curve, is a
0 g6 ~3 w' t. ]
graphical plot that illustrates the diagnostic ability of a binary
# N: K% f B8 [# ?) X" w
classifier system as its discrimination threshold is varied.
8 ?# ^5 E1 } T- k$ j
译:ROC曲线是由一系列因区分阈值变化产生的点,用于描述二分类模型的判断能力
' k" C# I# H4 s5 A, u" R
这里的关键在于 “its discrimination threshold is varied” ,因为对于一个二分类模型,它的输出结果其实是判断这个样本属于正样本的概率值,假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变“discrimination threashold”?我们根据每个测试样本属于正样本的概率值从大到小排序。下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率
0 o6 }. \+ Q t' D: y2 d
2020-4-19 11:48 上传
下载附件
(12.1 KB)
& {" X/ q) w3 C
然后我们按照样本的score值,从大到小依次作为阈值,当样本score值大于等于阈值时则判定为正样本,否则为负样本。
/ o' \- `7 R3 j5 z3 Y* x
例如第一个阈值取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! m, J5 q) c n$ H
J4 J( I- u g) I" ?" O
详细如下:
; _# F. |9 G, G2 o) y5 c1 b
2020-4-19 11:48 上传
下载附件
(203.28 KB)
( s7 L4 j W* Q% g: a( F" ~9 Y& C
由此我们便得到了一组(FPR,TPR)的值,可以绘制出ROC曲线:
6 A4 V, E! L! u7 ?3 S
2020-4-19 11:49 上传
下载附件
(63.27 KB)
$ g7 A; e) j, b! e6 W/ ]6 k; @+ n C
当我们将threshold设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。
! w8 ] K+ O% c! ]5 u6 A
) Q2 ]$ [) a; w6 h6 n8 L m
4.2 AUC
: A/ @) Y( P& n+ v. F( [) W0 h
2020-4-19 11:49 上传
下载附件
(90.3 KB)
3 U2 g6 H3 }! d" T5 T8 z
AUC(Area Under the Curve)是指ROC曲线下的面积,使用AUC值作为评价标准是因为有时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而AUC作为数值可以直观的评价分类器的好坏,值越大越好。
7 V9 P6 y/ \0 ?! l! W _
; x M# k: B5 C: C1 X# L
AUC是ROC曲线下的面积。
2 E# I* k' e, W+ o4 ]( _" c
AUC的取值为[0.5-1],0.5对应于对角线的“随机猜测模型”。
( y5 W( f" s: O7 @
AUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前面,从而能够更好地分类。
1 T* n' n1 A) V& q+ u
) X6 a# ~/ @# P+ j& E- Z# Q
从AUC判断分类器(预测模型)优劣的标准:
5 G0 ^! P0 ]% W
3 o1 i7 i* p7 A5 V: |% H
# C O7 M) w+ o; `# M0 ]% e
例如一个模型的AUC是0.7,其含义可以理解为:给定一个正样本和一个负样本,在70%的情况下,模型对正样本的打分(概率)高于对负样本的打分。
! G/ z6 }" f% }+ l$ z# I
; h, V3 X8 _, g4 ]7 `
三种AUC值示例:
5 a' C$ x, q& V, {0 e' H% }
2020-4-19 11:50 上传
下载附件
(47.71 KB)
, B3 R& k# B1 ~# I8 z0 \! ?
简单说:AUC值越大的分类器,正确率越高。
0 d$ h" y: ^( ?, s0 p
# ~) x! d4 j7 @& p4 X
那么为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?
7 V$ e- T5 L4 P
因为机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。也就是说AUC越高说明阈值分割所能达到的准确率越高。
. p6 w: z, _2 q9 k1 e
( y8 L, W: w+ R
小练习:
3 Z+ @, y8 p, y7 y% A
( V: \: E, O0 u( S0 `5 i' d
以下说法正确的是( ABD)。【不定项】
: q* E. J2 `* H/ ?! }# y
A 随着阈值的降低,TPR与FPR都会增大。
6 g0 J; I( Z W8 z, C* v5 |% N
B TPR与召回率的值是相同的。
8 v1 F* r5 {# c' v
C 如果AUC的值非常低,例如,0.1,则该模型效果很差,也很难调优。
. _4 M, D% |, N" `5 D( Z+ b
D 无论是什么分类模型,ROC曲线一定会经过(0, 0)与(1,1)这两个点。
, Z6 t4 g% N) ?& `4 G; c9 @5 s3 |
4.3 ROC曲线程序示例
9 k" B: r0 h1 ^8 D& P9 G
. w6 m A0 m' n8 y' d8 ?" @
我们首先来看一个简单的程序示例,借此来说明sklearn库中,ROC曲线的实现细节。
6 X5 a7 K& r- j9 n4 W8 J1 y
5 O5 J" Z3 @( f& Y* [
4.3.1 roc_curve函数的参数
' w% K; V! d. H
import numpy as np
8 E+ o* T! D% f/ b! s; I/ T C
from sklearn.metrics import roc_curve, auc, roc_auc_score
( ?5 u: f7 Z, b* y6 ^
y = np.array([0, 0, 1, 1])
8 d7 Y2 Z' x! F* D# C5 N
scores = np.array([0.2, 0.4, 0.35, 0.8])
6 A( w$ o" {: e
# 返回ROC曲线相关值。返回FPR,TPR与阈值。当分值达到阈值时,将样本判定为正类,
; r6 T8 ?1 H, @& v2 }; z
# 否则判定为负类。
9 V/ ?* A" U' H# p9 Q
# y_true:二分类的标签值(真实值)。
i, m& _8 A% U9 H$ Y+ U0 B4 e
# y_score:每个标签(数据)的分值或概率值。当该值达到阈值时,判定为正例,否则判定为负例。
' z% } U% P( p% N7 l
# 在实际模型评估时,该值往往通过决策函数(decision_function)或者概率函数(predict_proba)获得。
% a! T+ j( Q- x. `1 j3 {
# pos_label:指定正例的标签值。
5 M- P- B( {' L0 u% r! y d/ ?+ k' L
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=1)
% `5 l, |, J/ A P
print(f"fpr:{fpr}")
* f0 [" i) r5 j* ]2 u# S5 H- ~
print(f"tpr:{tpr}")
1 X! _& H$ j$ \+ n8 l
print(f"thresholds:{thresholds}")
: Z5 \: h- a. `: G) u2 n8 ]5 V3 e
# auc与roc_auc_score函数都可以返回AUC面积值,但是注意,两个函数的参数是不同的。
& U- {$ {6 D p7 \1 g8 V& q
print("AUC面积值:", auc(fpr, tpr))
9 b H1 L! G5 w3 B [ g
print("AUC面积得分:", roc_auc_score(y_true=y, y_score=scores))
# w8 R- V: ]- Z; \( d
#### 3.3.2 roc_curve函数的返回值
* \0 N. Y. h5 @3 d7 y, m# Y0 T8 k
% i2 Q$ Q* N# E9 O) }
结果:
7 k4 X1 `) H' L6 C- Q
2020-4-19 11:51 上传
下载附件
(40.48 KB)
1.8 是怎么来的?
9 D4 v/ t- e3 c9 q1 I- [2 D" h
1.8是阈值中最大值+1(0.8+1)得来的。为什么这么算?因为要使得最开始得到的所有阈值都不会超过这个值,才能过(0,0)和(1,1)这两个点。
* N4 x- i- m1 x/ }/ Q* i7 e! B9 V( Y
$ M( ^4 H4 b+ A9 F7 L
4.3.2 roc_curve函数的返回值
+ r+ l6 x3 o$ q4 x
+ Z8 X- o2 \4 F
roc_curve函数具有3个返回值:
0 n4 J# H( f2 Z9 \. g1 n, Q% U
& v9 X: K' k8 a* o
fpr 对应每个阈值(thresholds)下的fpr值。
1 A1 R! c, i' A! V" E7 q
tpr 对应每个阈值(thresholds)下的tpr值。
) T7 F- L: c0 m) U2 ~; k0 c
thresholds 阈值。
9 @$ x- v; K$ J3 U9 X; O: ]
roc_curve函数会从y_score参数中,选择部分元素作为阈值(选择哪些元素属于实现细节,会根据sklearn版本的不同,也可能会有所差异。),然后进行降序排列,作为roc_curve函数的第3个返回值(thresholds)。同时,根据thresholds中的每个元素(阈值),分别计算fpr与tpr。
6 K+ d+ L: b* `: C- X
iris = load_iris()
7 H$ V' M' z9 K) P, N
X, y = iris.data, iris.target
8 S0 @! ^: Y; T: j: ]$ p
X = X[y != 0, 2:]
: A+ D5 M% m& H( _" V
y = y[y != 0]
/ v0 L- r' [* E1 I. F: ] a- H: |5 F
y[y == 1] = 0
* t) r+ X' R) v. v+ P! }
y[y == 2] = 1
2 K- z$ E" B) s& m
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,
t& x' t: R( H2 x P+ S
random_state=2)
" g2 o& \+ n0 w h6 E
# lr = LogisticRegression(multi_class="multinomial", solver="lbfgs")
( M) e1 O' [* [3 X% F! D1 a
lr = LogisticRegression(multi_class="ovr", solver="liblinear")
* D2 C% D1 j7 ]$ Q5 G0 i$ l
lr.fit(X_train, y_train)
4 s/ r/ f' j+ o0 K7 r* B5 A" e
# 使用概率来作为每个样本数据的分值。
. Z" o* U' n! Y. u$ J9 \# l
probo = lr.predict_proba(X_test)
1 z3 O3 f1 A t) r( ]
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=probo[:, 1],
& G% T; a: U, c( G$ q9 K, `
pos_label=1)
" W5 q4 Y' c0 B. p
display(probo[:, 1])
% v2 \4 Y0 |$ i) C) N2 u
# 从概率中,选择若干元素作为阈值,每个阈值下,都可以确定一个tpr与fpr,
5 b% I& X. w! u* n# ]2 K
# 每个tpr与fpr对应ROC曲线上的一个点,将这些点进行连接,就可以绘制ROC曲线。
9 l5 y5 U1 `6 C% F$ q
display(thresholds)
' h$ M7 S* O2 V8 q8 {* J! F
& g+ j' A! n t; o
结果:
0 E% _0 T% t( O' H1 i2 m' T
2020-4-19 11:52 上传
下载附件
(23.53 KB)
) d( K; ?7 ~7 e
4 ` R/ @+ P/ v3 w5 w5 [
- F; {! [' O0 j( @% F5 C- e: i% R
# 随着阈值的不断降低,fpr与tpr都在不断的增大。
! i1 ^3 o3 M; C+ r
fpr, tpr
& @! c, y' D8 V3 @2 U
. D6 x. S% m0 |0 H4 z0 S
结果:
, Z/ C/ ?: ~8 p1 y
2020-4-19 11:52 上传
下载附件
(5.94 KB)
+ s# b f- Z9 @ t a S0 R( y. r5 I
% `3 E4 w) C% j7 o
4.3.3 绘制ROC曲线
* n3 n: A- ^* T- K" d
有了fpr与tpr的值,绘制ROC曲线是非常容易的,只不过是最简单的一个plot而已。
, d* M3 y! A, ]# \; U' L0 X/ p
plt.figure(figsize=(10, 6))
5 T! E! A- Q# L7 v
plt.plot(fpr, tpr, marker="o", label="ROC曲线")
H* X7 V* r" V
plt.plot([0,1], [0,1], lw=2, ls="--", label="随机猜测")
* ^# K! Y$ O1 r, d$ h* A
plt.plot([0, 0, 1], [0, 1, 1], lw=2, ls="-.", label="完美预测")
- Z4 s2 h+ r2 T6 z1 w: }# g' i, n
plt.xlim(-0.01, 1.02)
9 L8 k( y- B2 ~4 q, m) Z6 U
plt.ylim(-0.01, 1.02)
9 [0 m' {/ w) ]- N) n
plt.xticks(np.arange(0, 1.1, 0.1))
$ P9 h/ S* I+ T; i4 T
plt.yticks(np.arange(0, 1.1, 0.1))
$ D2 i' p6 K$ s$ M( L
plt.xlabel("False Positive Rate(FPR)")
% f* g7 d3 T& ?. q4 S
plt.ylabel("True Positive Rate(TPR)")
1 C# a! n L4 z2 }2 r
plt.grid()
/ d, H- _9 ^* K% @0 n5 H
plt.title(f"ROC曲线-AUC值为{auc(fpr, tpr):.2f}")
$ h' u$ X- u) P$ Z% v+ {5 u
plt.legend()
5 Z- w m/ x6 @4 z8 l' p0 `. e
plt.show()
: r6 E' @. t+ t5 j/ `: D) T
2020-4-19 11:53 上传
下载附件
(27.62 KB)
4 t7 l7 D( l. g0 B' a1 \
# S9 ]1 x3 {7 p1 g/ w" t- W$ n
5、总结
- ?% z0 f- }. N$ Y, l1 d1 a# ~
! `0 F( a! i4 P, t" R( ~' Q
混淆矩阵的含义。
/ H( P E# ^. X0 Q9 |& w
正确率,精准率,召回率与调和平均值F1的含义。
# O0 D% @$ b" c1 }
ROC与AUC。
C) C3 a; P' Q$ Y! ]
) q, N/ I4 @0 r5 {5 H
参考资料:
9 s( o& S6 J+ w& B: ?, m
1、https://blog.csdn.net/zuolixiangfisher/article/details/81328297
) e2 g1 e4 S$ ]; v5 g9 J! ~
2、https://www.jianshu.com/p/2feb00839154
. U' Y# a: u# I' `# M5 d
3、https://www.cnblogs.com/kamekin/p/9788730.html
7 f, u$ `9 a, |
4、https://www.jianshu.com/p/c61ae11cc5f6
: Y. k) {4 Q' {# \ s* Q
————————————————
5 n- L4 U5 `$ P; z7 J! l+ r1 R
版权声明:本文为CSDN博主「糖潮丽子~辣丽」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
8 Q# b% F F. M- a
原文链接:https://blog.csdn.net/qq_39783601/article/details/105600700
: J2 i6 [! y, S2 F2 H; L
/ ~3 X$ n' e! b; W% M: S
A1 y+ y1 X6 T/ N7 [; R. Z
作者:
1336671542
时间:
2020-4-19 12:50
非常感谢!!!!!!!!!!
5 L5 F9 H5 A \: m
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5