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