ROC曲线的解释(很形象)

时间:2022-09-10 18:03:47

几个概念

ROC曲线的解释(很形象)

场景

AdaBoost的基本分类器的线性组合

f(x)=m=1MαmGm(x)

最终的分类器

G(x)=sign(f(x))=sign(m=1MαmGm(x))

这里已知 {f(xi)|i=1,2,,N}{labeli|i=1,2,,N},前者是每个样本xi对应的基本分类器的输出的加权组合,后者是对应的标签数据。

接下来基于这两个数据做ROC曲线图。

作图

ROC曲线的解释(很形象)

绘图代码:

<code class="language-python hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#predStrengths 和classLabels都是299个元素的ndarray对象。</span>
ySum = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#variable to calculate AUC</span>
N = classLabels.shape[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#总样本个数</span>
numPosClas = np.sum(classLabels==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#样本中正例的个数</span>
yStep = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>/numPosClas;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#真阳率(在纵轴上)的分母是正样本的个数</span>
xStep = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>/(N-numPosClas) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#假阳率(在横轴上)的分母是负样本的个数</span>
srtidxs = predStrengths.argsort()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 从小到大排列的序号</span>

fig = plt.figure()
fig.clf()
ax = plt.subplot(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">111</span>)

cur = (<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#左上顶角坐标,全部样本都判为正,真阳率和假阳率都为1</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> idx <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> srtidxs: 
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#从值最小到值最大,作为判断门限,将大于该值的样本判为正,将小于等于该值的样本判为负</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> classLabels[idx] == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>: <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 样本为正,影响的是真阳率,判错了,所以真阳率要减小一个刻度</span>
        delX = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; 
        delY = yStep;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>: <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 样本为负,影响的是假阳率,盘对了,故假阳率要减小一个刻度</span>
        delX = xStep; 
        delY = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#每次x轴(即假阳率)调整时,将ySum加上当前的y轴刻度值,</span>
        ySum += cur[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] 

    ax.plot([cur[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],cur[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]-delX],[cur[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>],cur[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]-delY], c=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'b'</span>)
    cur = (cur[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]-delX,cur[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]-delY) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#更新坐标,从右上角向左下角画的曲线    </span>
ax.plot([<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>],[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>],<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'b--'</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 画一条对角线,从(0,0)到(1,1)</span>

auc = np.str( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%.4f"</span>%(ySum*xStep)) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#曲线下的面积</span>
plt.xlabel(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">u'假阳率'</span>,{<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'fontname'</span>:<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'STFangsong'</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'fontsize'</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>}); 
plt.ylabel(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">u'真阳率'</span>,{<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'fontname'</span>:<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'STFangsong'</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'fontsize'</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>})
plt.title(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">u'ROC曲线'</span>+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'(AUC = ('</span>+auc+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">')'</span>,{<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'fontname'</span>:<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'STFangsong'</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'fontsize'</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>})

ax.axis([<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]) 
fig.savefig(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'roc.png'</span>,dpi=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>,bbox_inches=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'tight'</span>)</code>