QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2725|回复: 1
打印 上一主题 下一主题

详细讲解分类模型评估

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-19 11:53 |只看该作者 |正序浏览
    |招呼Ta 关注Ta

    * N# V7 C/ w$ v8 g& ^7 U+ G详细讲解分类模型评估分类模型评估7 b/ w2 F# L2 S. K
    - \, V4 D- ^0 f% ^
    1、分类模型
    + k. [1 y9 F5 ^! |, W) ]主题:如何对分类模型进行评估3 j+ V' ?+ o' H
    目标:
    : Q) E) p0 f' T7 z- W2、混淆矩阵' M5 m9 X  e6 h$ u& J9 X
    3、评估指标
    9 W. c9 L/ O+ `6 k9 N8 |3.1 正确率" ~2 O2 C* f& u( x
    3.2 精准率
    & B6 L/ N. U) f3.3 召回率) L9 L( b7 q3 Y  I$ g
    3.4 调和平均值F1
    7 m% c7 u3 N4 ?4 y4、ROC和AUC
    4 `. Y0 Y2 y) k/ F& f4.1 ROC曲线+ M7 W  k% Y, @1 C
    如何画ROC曲线:  v( [! q7 @) T9 f6 ?
    4.2 AUC
    8 N# V8 [2 r0 p# Z& ~4.3 ROC曲线程序示例- M; h; U1 M- t. [- i8 N
    4.3.1 roc_curve函数的参数
    1 o& u3 x6 \: Z, W3 ]4.3.2 roc_curve函数的返回值
    2 l4 N+ \( p/ X6 E! a" P/ u; \4.3.3 绘制ROC曲线
    ' h0 k. E. l& h( a, F5、总结
    2 y- R" z5 j" c: {1、分类模型( e5 `( e/ b- X1 k4 o

    1 l4 s$ S- t1 a+ _分类问题在我们日常生活中处处可见,比如我们对帅哥的分类,可能对帅哥分为非常帅和一般帅。比如我们平时刷淘宝,淘宝根据我们平时的喜好给我们推送产品,那我们就会把产品分为感兴趣和不感兴趣两类。- G. J& n+ N! N( S
    上述所说的问题就是典型的分类问题,确切的说其实就是二分类问题。7 M  W" ]- f! S# V# R' u
    能够解决这些二分类问题的数学模型就被称为二分类模型。& y# x. W. I9 \
    用数学的方式表达就是,给定自变量X,代入到我们的分类模型F,会输出因变量y,y的取值为0或1,其中0代表负样本(一般帅的帅哥、不感兴趣的推送),1代表正样本(非常帅气的帅哥、感兴趣的推送)。
    / W5 m/ o! b4 v' `, k3 @  w; V( n3 d0 ^
    主题:如何对分类模型进行评估5 W: d: J: }6 F/ G' U% E, k

    ) p1 x) @3 E9 A* w" k目标:
    . s- N+ _5 C# O) m+ ]
    ; G3 O9 |# j* h; d能够熟知混淆矩阵的含义。
    7 y6 b/ B! m# O  m/ |8 u, G( _) I$ V能够使用各种指标对分类模型进行评估。" q/ Y# B: z. U* t$ r
    能够独立绘制ROC曲线,并熟悉该曲线细节。: |: ]0 ?: e( \8 s& M1 f" z8 U
    能够对样本不均衡进行处理(扩展内容)。( [( y1 A; a4 z# ^; }0 |
    2、混淆矩阵- q& M! ]0 r- j! x( P% O/ u- W
    6 \" R1 T% d( a4 H' j( {
    混淆矩阵,可以用来评估模型分类的正确性。  z$ p% c( I- g( h5 Z% R, T
    该矩阵是一个方阵,矩阵的数值用来表示分类器预测的结果,包括真正例(True Positive),假正例(False Positive),真负例(True Negative),假负例(False Negative)。
    + z4 c+ T2 l7 T# y9 |1 @) m9 x 1.png 1 l; F4 [- W5 z
    矩阵的形状是2 x 2,其中, - 矩阵的左上角表示,预测值为1,实际值为1(True Positive,简称TP); - 右上角表示预测值为1,实际值为0(False Positive,简称FP); - 左下角表示预测值为0,实际值为1(False Negative,简称FN); - 右下角表示预测值为0,实际值为0(True Negative,简称TN);
    7 Y5 L3 Y3 t  r4 G7 X; V  q7 Y9 F' ]1 c% Z
    真负例(TN)+ 假正例(FP)——每个类别真实存在的负例的数量
    8 V/ a, ~/ D. X7 y6 o, t假负例(FN)+ 真正例(TP)——每个类别真实存在的正例的数量
    ; j5 G4 O, p  M" N+ x4 `真负例(TN)+ 假负例(FN)——每个类别预测的真负例数量
    * X" G  e  a3 r/ v假正例(FP)+ 真正例(TP)——每个类别预测的真正例数量
    0 ~4 U# n' ~5 o8 f. |其中:
    7 i% I4 E! a" k, c
    2 ]) b# V- h$ Z3 ?1 |$ }5 sTP:真正例,实际为正预测为正;% K" X$ C* v4 M( j
    FP:假正例,实际为负但预测为正;
    + f) Z+ C" `5 BFN:假反例,实际为正但预测为负;
    % E% ?) |# Z. V4 T# gTN:真反例,实际为负预测为负7 c4 G7 f4 p/ e
    接下来,我们通过数据来看下鸢尾花的混淆矩阵:
    ; {# j1 L1 x% S0 J; h" M7 Kimport numpy as np( m9 a9 l3 n, }# v( y
    from sklearn.datasets import load_iris
    $ `1 @3 r, p7 @! J' \from sklearn.linear_model import LogisticRegression0 T$ V& ?; B% X9 S( B1 \5 C
    from sklearn.model_selection import train_test_split$ i1 O, _' @! A' X4 \; W2 ], x% y
    # 混淆矩阵: A/ F2 u' [5 {  J5 t
    from sklearn.metrics import confusion_matrix, A! X/ ?. c: ]# k1 G' P. N
    import matplotlib.pyplot as plt+ i8 g) Y! @  i9 z, f% h- z
    import warnings+ o9 e4 N. z& m$ C
    1 L/ `3 J( A# ~+ E
    plt.rcParams["font.family"] = "SimHei"% g3 V. _0 `% N3 g* W# r" a
    plt.rcParams["axes.unicode_minus"] = False8 o$ s* V# M1 u% L/ {3 V/ L: K; ]
    plt.rcParams["font.size"] = 126 m; i2 T3 N5 @" u( g( G
    warnings.filterwarnings("ignore")
    & }' Y* _: b$ g) m0 x0 d) q8 A. M+ I& \( b
    iris = load_iris()  #导入鸢尾花数据集: u' h9 [8 v( n8 q! W
    X, y = iris.data, iris.target
    2 b; u8 s  K" J# c. _X = X[y != 0, 2:]
    # S- Y% E4 E* M+ c8 E1 [y = y[y != 0]/ s# s7 I! h1 P6 n
    y[y == 1] = 0
    ; @7 Z* I% C$ S+ x% By[y == 2] = 1$ }( j8 S" p, a5 W) B' b
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)0 q+ y; P, S' N/ ]% _5 z
    lr = LogisticRegression()  #使用逻辑回归
    " V- t7 H9 V8 Z2 ?8 Vlr.fit(X_train, y_train)- N( A7 E6 M, P. u& K# i
    y_hat = lr.predict(X_test): S7 @1 I8 d6 z5 j" B7 M
    # 根据传入的真实值与预测值,创建混淆矩阵。* K9 A- H* I4 n6 I$ u1 l# V
    matrix = confusion_matrix(y_true=y_test, y_pred=y_hat)( D: p1 {4 V' v- F, U- L
    print(matrix)
    7 K0 W, |% f6 r$ V4 X. i) x' y4 e) K0 o9 v7 ~/ ~

    ; `/ V+ U1 ?7 k输出结果:
      F) m8 F: v$ B( H; u 2.png   q1 }6 C2 E: r# f4 O! n
    我们还可以对其进行可视化操作:- R1 s) {" w% O
    mat = plt.matshow(matrix, cmap=plt.cm.Blues, alpha=0.5)    #cmap 指定颜色图色系,alpha透明度. ^' Z, G' c+ V8 l
    label = ["负例", "正例"]2 w2 b; P9 C" G" M/ H
    ax = plt.gca()
    , z) d% k4 z: z0 _' Uax.set(xticks=np.arange(matrix.shape[1]), yticks=np.arange(matrix.shape[0]),/ y( u) n* ^6 O, _& }  W' ]
            xticklabels=label, yticklabels=label, title="混淆矩阵可视化\n",
    + `! M" C4 e- b# v6 {$ v0 V8 s        ylabel="真实值", xlabel="预测值")9 z# B5 k' K/ S$ Z) H
    for i in range(matrix.shape[0]):
    " Z8 f3 P6 G; B4 Q$ J9 p  \0 ^& d    for j in range(matrix.shape[1]):" @/ z! [4 o, ?# \4 q
            plt.text(x=j, y=i, s=matrix[i, j], va="center", ha="center")% V# ?4 v- j6 z. b. ?! K) P4 k
    a, b = ax.get_ylim()
    ) t$ @- K$ ^3 G0 }  s, Lax.set_ylim(a + 0.5, b - 0.5)7 k+ L% [' M6 F5 T0 T( v. P
    plt.show()! d  l; w4 ~% w. w' [" ^
    2 H2 W: g% s; v3 z

    : b- T/ J, p+ s* q: c- R' t代码解析:' @6 k* S" V- U% s* c: x, B
    matshow( ) 绘制矩阵,alpha 透明度. A' q+ q0 U  n( ]
    结果:
    ! a) X9 F/ O5 p  d: T 3.png " L# u' I9 x4 n  H
    练习:
    ! p7 L0 M- e( c6 c% b, t
    ( ?* C7 F* M$ m' O; h6 I' ~* O关于混淆矩阵,说法正确的是( ABCD)。【不定项】
    ( z! _6 B0 R5 tA 混淆矩阵可以用来评估分类模型。  o0 N4 P9 ]5 K% {3 f: X
    B 混淆矩阵中,TP与TN的数值越大,则分类的效果越好。- _3 O0 V# R9 T# Q/ Y
    C 混淆矩阵一行元素的和代表某个类别的实际数量。+ X! ~5 Q1 w& A
    D 混淆矩阵一列元素的和代表某个类别的预测数量。
    ! _% g0 q- K7 S' W3、评估指标
    5 y: i! w' y* \) R+ |0 [8 z- E6 z3 q% N, T/ t0 |
    对于分类模型,我们可以提取如下的评估指标:
    6 I* \6 ?. D7 W3 R9 N3 \4 N# d0 \. `# v8 l
    正确率(accuracy)
    ' c) D4 ~, B" W1 @2 t  }) S/ q+ Z) i精准率(precision)8 o6 u, W4 x6 K
    召回率(recall)
    3 J( G3 s6 R8 i6 @5 ~F1(调和平均值)
    % ~# `/ n; T2 R- A3.1 正确率
    # V" d, K9 }4 }: @: Q7 t 4.png & z+ o' C( L: U3 I; r
    正确率(准确率)定义如下:
    " m- z. L5 C# W. U2 m1 c: C9 \衡量所有样本被分类准确的比例。
    " a1 B  G. R4 v! g7 t$ `Accuracy = (TP+TN) / (TP+FP+TN+FN)7 ^: B" X0 n0 c
    " _: Z- Z9 G7 w
    预测正确的数量除以总数量。7 f2 r* A4 a2 I, t7 Y# |
    : Q' f& v0 F. z1 ^
    3.2 精准率
    * B" O' `7 W( b- J5 H1 w 5.png
    9 \- }( Z4 @# k- M$ \查准率(精准率)定义如下:2 s. l0 e; z, ^' H
    衡量正样本的分类准确率,就是说被预测为正样本的样本有多少是真的正样本。
    : |* @& X* O- i0 E' F" [$ lPrecision = TP / (TP+FP)
    : q( y5 E& e" o2 g9 N& d
    4 H. \! T( d2 j$ a8 H+ y$ z5 K精准率只考虑正例。2 L' k# w6 g" |- }; {1 T( S( T
    1 O$ P& g" b9 l0 u2 ~
    3.3 召回率
    % c$ I0 G7 r' F4 p$ O' s 6.png
    ! A3 G: q) f. O2 G* s" o查全率(召回率)定义如下:* v: r" j9 M: d, v, s7 T
    表示分类正确的正样本占总的正样本的比例。1 }  T" c3 ?) G. I
    Recall = TP / (TP+FN)
    * m) w0 F7 V3 e1 K  a  h7 M0 Y7 z* h) S: Z) S" c- a
    4 W8 H/ v$ L$ j" n; c
    3.4 调和平均值F1% j0 L  X3 R  _( f2 o
    7.png
    2 Q+ P* j8 E" ~- Z9 J) Z4 K/ NF值(F1-scores)调和平均值F1定义如下:& H6 k0 h. n4 B! A  s
    精确率和召回率的调和平均。" Q$ J5 E7 n  {1 E( g; @. w
    精准率Precision和召回率Recall加权调和平均数,并假设两者一样重要。* O( L- w8 S  c! G7 R9 W: `
    7 L* F. X) E4 u$ A$ Z- J$ {! X+ o
    F1-score = (2Recall*Precision) / (Recall + Precision)3 r7 e3 F# i9 T6 ~& v4 {: e4 r) J

    & S1 Q1 S: J# Y6 u) @4 t精准率和召回率是一对矛盾的度量。一般来说,精准率高时,召回率往往偏低;而召回率高时,精准率往往偏低。通常只有在一些简单任务中,才可能使二者都很高。
    / U3 e6 S3 e1 Y4 {  o, T最好的分类器当然是准确率、精确率,召回率都为1,但实际场景中几乎是不可能的,而且精确率和召回率往往会相互影响,一个高了另一个会有所下降,因此在实际应用中要根据具体需求做适当平衡。* X  }/ F' J# n0 c" V3 X
    让我们做个练习加深下印象吧!
    / i( m, O( u1 ^  o: c
    ( X9 n  M6 b  E以下说法正确的是( C )。/ x" v8 c1 o8 p  H9 s# U; k8 I: ]
    A 使用正确率去评估一个分类模型,效果会比精准率更好。
    ! w# u( @: a5 }, V* OB 使用精准率去评估一个分类模型,效果会比召回率更好。
    ) B. ]  T- x$ ~2 n/ cC 精准率与召回率通常要联合使用。: I+ p& o1 B$ w0 C2 c/ R  w; q
    D 精准率与召回率如果有一个值较低,F1值也可能会较高。+ o9 L3 o: q: j/ _$ }, B" }
    如果精准率和召回率我们只能选择重视一个,我们会更看重( C )。
    & O9 W, W9 e4 i/ c( ?* M4 Z$ `& u4 SA 精准率。
    4 C; q; l/ X+ y8 aB 召回率。
    : n" a: P) @) C. h. ZC 具体场景不同,重视谁也会不同。
    & j! H$ [5 M  o4 f5 e) U4 e6 s% z接下来我们通过程序来说明下:
    . i! F% q# r* ^$ Z* D9 g0 nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score- r: G* e6 K5 M' W5 L5 Q2 v5 |. J

    ) }6 l0 V& u  U' A' Oprint("正确率:", accuracy_score(y_test, y_hat))/ c- G% S9 H/ r2 Y
    # 默认将1类别视为正例,可以通过pos_label参数指定。
    2 _% Y% j* t! J- a) E2 G! Xprint("精准率:", precision_score(y_test, y_hat)), T$ ?! r" {; j/ X6 @
    print("召回率:", recall_score(y_test, y_hat))! I3 ^$ G: a" T, r" |) \
    print("F1调和平均值:", f1_score(y_test, y_hat))
    ; s8 N( p( V- f# 我们也可以调用逻辑回归模型对象的score方法,也能获取正确率。3 a! J  ]/ S& {! \0 H9 l3 Q  v
    # 但是需要注意,score方法与f1_score函数的参数是不同的。- M* r% }$ G$ l+ v0 I/ M
    print("score方法计算正确率:", lr.score(X_test, y_test))2 u$ z  S6 s  O9 ^5 ^% I" U4 d
    / e8 O* }" o/ F  D& Y+ K+ q2 L

    2 J+ R& k5 z% R: D# O/ B3 @结果:
    / z; R( E( H8 i9 c  g 8.png ) l& N- b% u* G! w8 U- f0 F0 _0 X
    除此之外,我们也可以使用classification_report函数来查看模型的分类统计信息,该方法会返回字符串类型,给出相关的分类指标评估值。: g" @0 \" D, f+ H; X. H
    from sklearn.metrics import classification_report
    8 h( w5 A/ D6 M5 p
    " O! _8 ~# G& D) G8 m+ Z6 I- Yprint(classification_report(y_true=y_test, y_pred=y_hat))+ H0 L5 c9 N0 U0 b

    6 u' t0 o8 D4 c
    & G2 x0 I- x+ ^: J# H8 `结果:. _! ^: N4 F% z% ?
    9.png + T/ J2 s. }! [( _
    0 u/ P9 o: Q' U4 H
    练习:# d4 R- `$ C4 B
    . F7 E$ L" n$ Q- _- Z7 \
    如果使用精准率与召回率评估二分类模型时,我们应该将哪个类别设置为正例? (B)
    1 {4 _7 }* E% X8 ]* G, zA 随意9 `( T0 T. @! _7 n+ p6 U+ r
    B 关注的类别! H) ]% K! b4 G. J% w. D
    C 不关注的类别
    4 ^4 ?0 T7 m/ N1 O# S0 k; [4、ROC和AUC- [+ X( y' H) ~6 S  d! U0 W' x

    9 ?- q1 t/ \" F! C" ]3 CROC(Receiver Operating Characteristic)曲线和AUC常被用来评价一个二值分类器(binary classifier)的优劣。9 ^4 o, |# ?- N  k* ~% h

    - ]: X" z% p3 _0 u0 k; g5 E4.1 ROC曲线( v2 l( }# H* z
    10.png # t0 ^" g/ s9 a: G! H/ C* s
    ROC曲线(Receiver Operating Characteristic——受试者工作特征曲线),使用图形来描述二分类系统的性能表现。图形的纵轴为真正例率(TPR——True Positive Rate),横轴为假正例率(FPR——False Positive Rate)。其中,真正例率与假正例率定义为:  M; n: V$ o# r( U! z# t  \
    4 e% h2 d4 k# m
    ROC曲线通过真正例率(TPR)与假正例率(FPR)两项指标,可以用来评估分类模型的性能。真正例率与假正例率可以通过移动分类模型的阈值而进行计算。随着阈值的改变,真正例率与假负例率也会随之发生改变,进而就可以在ROC曲线坐标上,形成多个点。
    ; M% [+ F* d6 L" _
    # E2 l( Y3 s4 j2 D3 }' ~# NROC曲线反映了FPR与TPR之间权衡的情况,通俗来说,即在TPR随着FPR递增的情况下,谁增长得更快,快多少的问题。TPR增长得越快,曲线越往上凸,模型的分类性能就越好。
    + t1 D& X  e% ~$ s0 S0 R. w- G9 L. M
    & v4 I- ~5 C' J) F9 XROC曲线如果为对角线,则可以理解为随机猜测。如果在对角线以下,则其性能比随机猜测还要差。如果ROC曲线真正例率为1,假正例率为0,即曲线为与构成的折线,则此时的分类器是最完美的。
    6 t% ^2 r( ^5 u$ z
    7 `/ @3 }  `: X( @3 a' X: f. c下图就是ROC曲线的一个示意图:3 r1 q$ G* M5 R' F" h
    11.png * d/ o9 v/ P; e) j3 J
    ROC曲线横坐标是FPR(False Positive Rate),纵坐标是TPR(True Positive Rate)* [; e+ p$ X4 x; ~7 n
    接下来我们考虑ROC曲线图中的四个点和一条线。
    8 R4 g6 n; w  k: D, c: |7 B0 m  u' O
    第一个点,(0,1),即FPR=0, TPR=1,这意味着FN(false negative)=0,并且FP(false
    ( r: a6 R/ e) ?positive)=0。这是一个完美的分类器,它将所有的样本都正确分类。
    2 b- ]3 a. a. k! f  C第二个点,(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。
    ( d  L7 `) J' W第三个点,(0,0),即FPR=TPR=0,即FP(false positive)=TP(true
    ! U& N* v3 Z: A2 `1 k; ?1 I& lpositive)=0,可以发现该分类器预测所有的样本都为负样本(negative)。
    ! t& f+ B) n, H+ M  J' H第四个点(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好。
    7 p& Q! H$ y2 S# a! j- {如何画ROC曲线:
    9 C9 g* X! W  ^. m
    . Q# e0 d" x; i, |2 {对于一个特定的分类器和测试数据集,显然只能得到一组FPR和TPR结果,而要得到一个曲线,我们实际上需要一系列FPR和TPR的值,这又是如何得到的呢?我们先来看一下wikipedia上对ROC曲线的定义:
    & {9 `  }0 W) ?3 A2 O8 u" G7 O  F. N: ^4 E1 l3 \2 F3 I
    A receiver operating characteristic curve, i.e. ROC curve, is a
    ! {7 f* F3 Z* a# D( M( S& S  \- wgraphical plot that illustrates the diagnostic ability of a binary% t( s( t6 H) s; M6 C
    classifier system as its discrimination threshold is varied.
    6 [. G8 d) [4 x5 B' N译:ROC曲线是由一系列因区分阈值变化产生的点,用于描述二分类模型的判断能力( e  \  C( V" z% i# I4 D
    这里的关键在于 “its discrimination threshold is varied” ,因为对于一个二分类模型,它的输出结果其实是判断这个样本属于正样本的概率值,假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变“discrimination threashold”?我们根据每个测试样本属于正样本的概率值从大到小排序。下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率' W: |) g0 s6 X: H. d
    12.png 5 k  u3 V9 L  E8 `1 F; N, c
    然后我们按照样本的score值,从大到小依次作为阈值,当样本score值大于等于阈值时则判定为正样本,否则为负样本。, f& y* ?/ g( J2 Q
    例如第一个阈值取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 E  I! j* [+ ]  g4 I. ?9 }
    - @4 U$ P1 V' R& {! @; }9 Y详细如下:- @( f5 D3 `8 i- O7 L7 t9 F% d
    13.png $ }4 a  @6 H: a8 R+ u2 X
    由此我们便得到了一组(FPR,TPR)的值,可以绘制出ROC曲线:6 Y; }% c6 c) N
    14.png
    " Y! |9 i; x( d4 u0 O当我们将threshold设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。, }& L! u, V/ N

    ) e8 }. F  b# H1 U) O* ?" P4.2 AUC2 p+ J6 ^6 l8 \
    15.png 7 P2 I% r8 ]- b/ z1 B% D$ u
    AUC(Area Under the Curve)是指ROC曲线下的面积,使用AUC值作为评价标准是因为有时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而AUC作为数值可以直观的评价分类器的好坏,值越大越好。
    + x0 _8 l( W" {, r3 K2 s% m- V* }; Z/ d3 U0 w# o, b7 u* b
    AUC是ROC曲线下的面积。3 {5 Q5 H" N) E8 _0 m! p5 ?
    AUC的取值为[0.5-1],0.5对应于对角线的“随机猜测模型”。3 e' l- N9 G0 r' b
    AUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前面,从而能够更好地分类。  p, i. k+ ^" u2 T8 |5 G( K) O

    . e( o4 O  w! ^4 d从AUC判断分类器(预测模型)优劣的标准:2 n" n$ Q0 j" w

    8 \7 X3 X1 {8 ^  s+ \& l! A# v: C) L3 H8 h6 J1 q
    例如一个模型的AUC是0.7,其含义可以理解为:给定一个正样本和一个负样本,在70%的情况下,模型对正样本的打分(概率)高于对负样本的打分。; }2 @8 q0 U4 q% e
    " ]& ?  L( Q' d% g5 c
    三种AUC值示例:
    2 X1 Z6 C1 Y4 b% q% z$ j( S 16.png
    5 B- P8 f- r* W9 G$ I简单说:AUC值越大的分类器,正确率越高。" _' C6 z; ?8 C0 D! \" l

    ) Y* {2 x% B3 e0 a! m那么为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?$ X7 N# R, p$ D6 z: ?
    因为机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。也就是说AUC越高说明阈值分割所能达到的准确率越高。( ]5 z& L2 Y0 @0 _
    ! K. x; Q; ?: ~  @+ I
    小练习:
      s2 D7 \6 Q+ F2 z/ p4 N/ E/ k' F) {- m
    以下说法正确的是( ABD)。【不定项】. f/ z& F* R+ ^9 t/ w5 p1 v1 @8 _
    A 随着阈值的降低,TPR与FPR都会增大。  U' H$ y4 v# `6 i: e. p" i
    B TPR与召回率的值是相同的。  o! c# i$ ^' g, |
    C 如果AUC的值非常低,例如,0.1,则该模型效果很差,也很难调优。: ?: X* \# T: \
    D 无论是什么分类模型,ROC曲线一定会经过(0, 0)与(1,1)这两个点。
    . n, J! c$ O8 @8 v7 k4.3 ROC曲线程序示例
    % l: f1 o1 l6 F3 L7 M' v
    : Z+ x. R1 t3 m* w1 A; j我们首先来看一个简单的程序示例,借此来说明sklearn库中,ROC曲线的实现细节。
    8 c. ?' t, E5 G# \5 ?: Z* {0 \/ D6 o" q
    4.3.1 roc_curve函数的参数- \# @, x  e# @( }: y
    import numpy as np
    . h' k5 B. X0 A+ R" A# Jfrom sklearn.metrics import roc_curve, auc, roc_auc_score6 q7 x- `  |9 G) O; e+ a0 f
    y = np.array([0, 0, 1, 1])
    9 B" c, `  J5 Dscores = np.array([0.2, 0.4, 0.35, 0.8])
    ; k: D/ I9 W1 B0 b' M# 返回ROC曲线相关值。返回FPR,TPR与阈值。当分值达到阈值时,将样本判定为正类,( {# @# {$ W, i3 L
    # 否则判定为负类。
    9 f1 h1 Z3 R9 F+ ?# y_true:二分类的标签值(真实值)。
    0 l7 u5 G& Y8 u) d% L+ J. K5 @# y_score:每个标签(数据)的分值或概率值。当该值达到阈值时,判定为正例,否则判定为负例。1 g$ e4 w5 G3 s3 N: g# ~9 ^! {% f6 e
    # 在实际模型评估时,该值往往通过决策函数(decision_function)或者概率函数(predict_proba)获得。! D0 c+ V% q: s3 s4 u8 A
    # pos_label:指定正例的标签值。
    " z+ ~8 h7 X0 k( ?0 ?fpr, tpr, thresholds = roc_curve(y, scores, pos_label=1)+ l/ T" G) ^1 i
    print(f"fpr:{fpr}")1 u8 Y6 G! m$ F. o
    print(f"tpr:{tpr}")# b6 ^, `. m* {  v+ ]
    print(f"thresholds:{thresholds}")/ v: k- C  w1 e
    # auc与roc_auc_score函数都可以返回AUC面积值,但是注意,两个函数的参数是不同的。$ S1 E3 {9 C0 l
    print("AUC面积值:", auc(fpr, tpr))
    / ~9 h8 a5 G# l5 ~print("AUC面积得分:", roc_auc_score(y_true=y, y_score=scores))
    5 I4 Y5 L# I/ g9 V1 {2 E#### 3.3.2 roc_curve函数的返回值
    $ p$ ~& N! g: I, M/ y1 T
    / M/ Y0 v- [2 I3 y结果:2 u$ f+ h4 Q' X+ {
    17.png 1.8 是怎么来的?
    / s" A; U2 u  J) D1.8是阈值中最大值+1(0.8+1)得来的。为什么这么算?因为要使得最开始得到的所有阈值都不会超过这个值,才能过(0,0)和(1,1)这两个点。* M) a( y% M4 V  K

    # v2 w. s3 y4 `* e0 ?! }" `9 R4 {4.3.2 roc_curve函数的返回值
    7 U( u. a6 H- b0 N% b
    & S% f# M' d  o+ g) vroc_curve函数具有3个返回值:
    " G6 D; B2 ?6 a+ z
    ! L  m& y7 v. H* D! m5 E7 L9 Lfpr 对应每个阈值(thresholds)下的fpr值。
    & b7 H" l3 j- F4 c: v% ?/ Ztpr 对应每个阈值(thresholds)下的tpr值。; J7 r9 P2 @+ y4 r. u! l
    thresholds 阈值。
    & [7 E. i' H( u, ~roc_curve函数会从y_score参数中,选择部分元素作为阈值(选择哪些元素属于实现细节,会根据sklearn版本的不同,也可能会有所差异。),然后进行降序排列,作为roc_curve函数的第3个返回值(thresholds)。同时,根据thresholds中的每个元素(阈值),分别计算fpr与tpr。
    4 ~6 d; f. a! g. Z- i- v. X9 u  Riris = load_iris()7 X: a. f% O) j2 u
    X, y = iris.data, iris.target/ H9 T' R" C4 a' G4 O& k! a. x1 ^
    X = X[y != 0, 2:]
    , p1 P4 ]( ]  ^0 P8 Gy = y[y != 0]
    9 i4 e' u, {/ ^. d0 P' O8 hy[y == 1] = 0' c  m) U" K- m! W8 k
    y[y == 2] = 1( J) R0 _6 C( m5 F  P( p
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,9 W1 n! Y5 y6 R5 U) V- z. S0 r
    random_state=2)
    ! t% o; G$ Z6 ?& x! |0 \# lr = LogisticRegression(multi_class="multinomial", solver="lbfgs")
    7 E/ ~. D6 Z$ e% S  b! Klr = LogisticRegression(multi_class="ovr", solver="liblinear")
    6 C8 D3 ^! H1 i1 j% ?' m% x& Plr.fit(X_train, y_train)- t! Y$ C1 l8 P
    # 使用概率来作为每个样本数据的分值。
    7 R/ }# H; F2 l5 rprobo = lr.predict_proba(X_test)) M- h# _0 {* `/ o' Z
    fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=probo[:, 1],, J/ S2 ?# J. h& {, a  i
    pos_label=1)
    ; u) n* _1 E: L$ \0 f! K6 g) Q2 ~! mdisplay(probo[:, 1])
    - g, r2 D1 L2 I* [! Z* B# 从概率中,选择若干元素作为阈值,每个阈值下,都可以确定一个tpr与fpr,6 Y+ n% }5 [: M& ]+ c  Y* b  c( i
    # 每个tpr与fpr对应ROC曲线上的一个点,将这些点进行连接,就可以绘制ROC曲线。
    ; j7 I, I& k: V6 K2 A$ e' Ddisplay(thresholds)
    7 a; A! z: Q  ~" B6 Q% p& X; z5 O* R" @* T
    结果:
    ; ~1 R! y9 ^) A  ?% S 18.png 8 O0 Y, Z+ k- ~, @

    # e0 ~; y: K1 p; u3 T  u
    3 }: [/ z$ x; y. ?; A# 随着阈值的不断降低,fpr与tpr都在不断的增大。/ }# g6 l# v0 n6 O4 \8 _: F
    fpr, tpr4 h" A1 ?; P2 u; v: n/ O- ]

      z9 S' C6 ?. L结果:/ a. J" V$ q/ f2 d
    19.png
    6 [9 A/ _# z3 d+ B/ W" B0 C7 S2 }* y
    9 n; w2 t" c4 Q4 }$ n5 E4.3.3 绘制ROC曲线# I/ w: b1 _( h! f8 ]3 H
    有了fpr与tpr的值,绘制ROC曲线是非常容易的,只不过是最简单的一个plot而已。
    7 P% \6 y0 Q5 T  ]; E! Xplt.figure(figsize=(10, 6))" H4 x2 [( ?4 p# O* ?0 I" N
    plt.plot(fpr, tpr, marker="o", label="ROC曲线")/ C0 [7 s& y/ n; N1 o8 W/ N
    plt.plot([0,1], [0,1], lw=2, ls="--", label="随机猜测")5 ^" `, Z1 }& z6 t
    plt.plot([0, 0, 1], [0, 1, 1], lw=2, ls="-.", label="完美预测")/ D3 P/ r  c# H) g2 u
    plt.xlim(-0.01, 1.02)4 E# Z# K) ~, o) k" r
    plt.ylim(-0.01, 1.02)8 h% }' h3 B1 l+ B
    plt.xticks(np.arange(0, 1.1, 0.1))
    : Y) Z! v* D! R& Nplt.yticks(np.arange(0, 1.1, 0.1))
    * M3 y4 g0 }4 S! L/ a. hplt.xlabel("False Positive Rate(FPR)")
    4 S. D% r& Z- b2 S+ q% r& M$ I( U8 Tplt.ylabel("True Positive Rate(TPR)")+ }( p# h  D. T+ S4 m
    plt.grid()4 m8 T9 D! [8 z( K
    plt.title(f"ROC曲线-AUC值为{auc(fpr, tpr):.2f}")
    0 K1 a) ]; S. u' m  e- }5 yplt.legend()8 ?9 l; e* S) b! }+ `
    plt.show()
    * S- ?) _! n! ]! I6 t 20.png
    ) f% v# Y& j) `- i+ Q! `
    1 w2 h+ ~" P* R3 d. E& S5、总结
    9 ~; ?  l6 M+ \; c1 H$ u/ [) T  V  `: W- L: l8 @+ o; `9 }! R
    混淆矩阵的含义。. o  G% N' t% {6 ]; M
    正确率,精准率,召回率与调和平均值F1的含义。
    : x) s- v0 q' x8 Q& EROC与AUC。. B4 a+ e+ Q+ B0 ^5 s% P+ C+ C

      r5 p# I) @" [' @. P1 l) n参考资料:+ n0 a% U- `2 |# S, f0 `
    1、https://blog.csdn.net/zuolixiangfisher/article/details/81328297( y8 D* v5 ~9 @  b
    2、https://www.jianshu.com/p/2feb00839154) l5 E5 ?! h7 c$ U1 `
    3、https://www.cnblogs.com/kamekin/p/9788730.html
    7 m' B2 T; q, N- D. B( r' @* ~1 K4、https://www.jianshu.com/p/c61ae11cc5f6
    3 r( {) n! _& J% ?( b————————————————
    ! k* Q  ^0 T! A; b7 v版权声明:本文为CSDN博主「糖潮丽子~辣丽」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    - P7 f  a+ j* k0 p# U' ~原文链接:https://blog.csdn.net/qq_39783601/article/details/1056007003 @. [" e" I& e( B3 ^3 I* g4 w

    ! I& C2 a* M9 c6 U% ?
    : J3 F9 ~6 N, \3 L  ]0 ]
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信

    0

    主题

    1

    听众

    11

    积分

    升级  6.32%

  • TA的每日心情
    开心
    2020-4-19 10:15
  • 签到天数: 2 天

    [LV.1]初来乍到

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-6-17 06:24 , Processed in 0.517975 second(s), 59 queries .

    回顶部