ROC เฉลี่ยสำหรับการตรวจสอบความถูกต้องข้าม 10 เท่าพร้อมการประมาณการความน่าจะเป็น


15

ฉันวางแผนที่จะใช้ซ้ำ (10 ครั้ง) แบ่งการตรวจสอบข้ามแบบ 10 เท่าบนชั้นประมาณ 10,000 รายโดยใช้อัลกอริทึมการเรียนรู้ของเครื่อง ทุกครั้งที่การทำซ้ำจะกระทำกับเมล็ดสุ่มที่แตกต่างกัน

ในกระบวนการนี้ฉันสร้างการประมาณความน่าจะเป็น 10 อินสแตนซ์สำหรับแต่ละกรณี 1 อินสแตนซ์ของการประมาณความน่าจะเป็นสำหรับแต่ละการทำซ้ำ 10 ครั้งของการตรวจสอบความถูกต้องข้าม 10 เท่า

ฉันสามารถเฉลี่ย 10 ความน่าจะเป็นสำหรับแต่ละกรณีและจากนั้นสร้างเส้นโค้ง ROC เฉลี่ยใหม่ (แทนผลลัพธ์ของ CV 10 เท่าซ้ำ) ซึ่งสามารถเปรียบเทียบกับเส้นโค้ง ROC อื่น ๆ โดยการเปรียบเทียบแบบคู่

คำตอบ:


13

จากคำอธิบายของคุณดูเหมือนว่าเหมาะสม: ไม่เพียง แต่คุณสามารถคำนวณเส้นโค้ง ROC เฉลี่ย แต่ยังรวมถึงความแปรปรวนรอบ ๆ เพื่อสร้างช่วงความมั่นใจ ควรให้แนวคิดว่าโมเดลของคุณมีความเสถียรแค่ไหน

ตัวอย่างเช่นนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ที่นี่ฉันใส่เส้นโค้ง ROC แต่ละเส้นรวมถึงเส้นโค้งเฉลี่ยและช่วงความมั่นใจ มีพื้นที่ที่เส้นโค้งเห็นด้วยดังนั้นเราจึงมีความแปรปรวนน้อยกว่าและมีพื้นที่ที่ไม่เห็นด้วย

สำหรับ CV ซ้ำคุณสามารถทำซ้ำหลาย ๆ ครั้งและรับค่าเฉลี่ยรวมในแต่ละเท่า:

ป้อนคำอธิบายรูปภาพที่นี่

มันค่อนข้างคล้ายกับภาพก่อนหน้า แต่ให้การประมาณที่มีเสถียรภาพมากกว่า (เช่นความน่าเชื่อถือ) ของค่าเฉลี่ยและความแปรปรวน

นี่คือรหัสเพื่อรับพล็อต:

import matplotlib.pyplot as plt
import numpy as np
from scipy import interp

from sklearn.datasets import make_classification
from sklearn.cross_validation import KFold
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve

X, y = make_classification(n_samples=500, random_state=100, flip_y=0.3)

kf = KFold(n=len(y), n_folds=10)

tprs = []
base_fpr = np.linspace(0, 1, 101)

plt.figure(figsize=(5, 5))

for i, (train, test) in enumerate(kf):
    model = LogisticRegression().fit(X[train], y[train])
    y_score = model.predict_proba(X[test])
    fpr, tpr, _ = roc_curve(y[test], y_score[:, 1])

    plt.plot(fpr, tpr, 'b', alpha=0.15)
    tpr = interp(base_fpr, fpr, tpr)
    tpr[0] = 0.0
    tprs.append(tpr)

tprs = np.array(tprs)
mean_tprs = tprs.mean(axis=0)
std = tprs.std(axis=0)

tprs_upper = np.minimum(mean_tprs + std, 1)
tprs_lower = mean_tprs - std


plt.plot(base_fpr, mean_tprs, 'b')
plt.fill_between(base_fpr, tprs_lower, tprs_upper, color='grey', alpha=0.3)

plt.plot([0, 1], [0, 1],'r--')
plt.xlim([-0.01, 1.01])
plt.ylim([-0.01, 1.01])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.axes().set_aspect('equal', 'datalim')
plt.show()

สำหรับประวัติย่อซ้ำ:

idx = np.arange(0, len(y))

for j in np.random.randint(0, high=10000, size=10):
    np.random.shuffle(idx)
    kf = KFold(n=len(y), n_folds=10, random_state=j)

    for i, (train, test) in enumerate(kf):
        model = LogisticRegression().fit(X[idx][train], y[idx][train])
        y_score = model.predict_proba(X[idx][test])
        fpr, tpr, _ = roc_curve(y[idx][test], y_score[:, 1])

        plt.plot(fpr, tpr, 'b', alpha=0.05)
        tpr = interp(base_fpr, fpr, tpr)
        tpr[0] = 0.0
        tprs.append(tpr)

แหล่งที่มาของแรงบันดาลใจ: http://scikit-learn.org/stable/auto_examples/model_selection/plot_roc_crossval.html


3

มันไม่ถูกต้องสำหรับความน่าจะเป็นโดยเฉลี่ยเพราะมันจะไม่แสดงการคาดคะเนที่คุณพยายามตรวจสอบและเกี่ยวข้องกับการปนเปื้อนในตัวอย่างการตรวจสอบความถูกต้อง

โปรดทราบว่าอาจจำเป็นต้องมีการตรวจสอบความถูกต้องไขว้ซ้ำ 10 ครั้งเพื่อให้ได้ความแม่นยำที่เพียงพอ หรือใช้ bootstrap optimism ของ Efron-Gong ซึ่งต้องการการวนซ้ำน้อยลงสำหรับความแม่นยำเดียวกัน (ดูเช่นฟังก์ชั่นR rmsแพ็คเกจvalidate)

เส้นโค้งของ ROC นั้นไม่สามารถแก้ไขปัญหานี้ได้อย่างชาญฉลาด ใช้คะแนนความแม่นยำที่เหมาะสมและใช้ร่วมกับ -index (ความน่าจะเป็นที่สอดคล้องกัน; AUROC) ซึ่งง่ายต่อการจัดการมากกว่าเส้นโค้งเนื่องจากสามารถคำนวณได้ง่ายและรวดเร็วโดยใช้สถิติ Wilcoxon-Mann-Whitneyc


คุณช่วยอธิบายเพิ่มเติมได้ไหมว่าทำไมการหาค่าเฉลี่ยไม่ถูกต้อง
DataD'oh

ตามที่ระบุไว้แล้ว คุณต้องตรวจสอบการวัดที่คุณจะใช้ในฟิลด์
Frank Harrell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.