ตัวชี้วัดการจำแนกหลายป้ายบน scikit


19

ฉันกำลังพยายามสร้างตัวแยกประเภทแบบหลายป้ายกำกับเพื่อกำหนดหัวข้อให้กับเอกสารที่มีอยู่โดยใช้ scikit

ฉันกำลังประมวลผลเอกสารของฉันผ่านพวกเขาผ่านTfidfVectorizerป้ายผ่านที่MultiLabelBinarizerและสร้างOneVsRestClassifierด้วยการSGDClassifierเป็นประมาณการ

อย่างไรก็ตามเมื่อทำการทดสอบลักษณนามของฉันฉันได้รับคะแนนสูงสุดเพียง. 29ซึ่งจากสิ่งที่ฉันได้อ่านนั้นค่อนข้างต่ำสำหรับปัญหาที่คล้ายกัน ฉันลองตัวเลือกหลายอย่างใน TfidfVectorizer เช่น stopwords, unigrams, stemming และไม่มีอะไรน่าจะเปลี่ยนผลลัพธ์ได้มากนัก

ฉันยังเคยGridSearchCVได้รับพารามิเตอร์ที่ดีที่สุดสำหรับตัวประมาณของฉันและตอนนี้ฉันไม่มีแนวคิดว่าจะลองทำอะไรต่อไป

ในเวลาเดียวกันจากสิ่งที่ฉันเข้าใจว่าฉันไม่สามารถใช้scikit.metricsกับOneVsRestClassifierดังนั้นฉันจะได้รับตัวชี้วัดบางอย่าง (F1, Precision, Recall และอื่น ๆ ) เพื่อหาว่ามีอะไรผิดปกติหรือไม่

อาจเป็นปัญหากับคลังข้อมูลของฉันหรือไม่

ปรับปรุง: ฉันยังพยายามใช้CountVectorizerและHashingVectorizerและวิธี pipeline พวกเขาไปTfidfTransformerแต่ผลที่มีลักษณะคล้ายกัน ดังนั้นฉันเดาว่าวิธีการแบบถุงคำกำลังทำดีที่สุดในโดเมนโทเค็นและส่วนที่เหลือขึ้นอยู่กับลักษณนาม ...


1
การวัด 0.29 คืออะไร ความถูกต้อง? อื่น ๆ อีก?
Sycorax พูดว่า Reinstate Monica

@GeneralAbrial ตามเอกสาร scikit ทำงานscoreบนลักษณนามReturns the mean accuracy on the given test data and labels. In multi-label classification, this is the subset accuracy which is a harsh metric since you require for each sample that each label set be correctly predicted.
mobius

นั่นคือสิ่งที่คุณทำ? ยังไม่ชัดเจนจากคำถามของคุณว่าเป็นกรณีนี้ดังนั้นจึงเป็นคำถามที่สมเหตุสมผลอย่างสมบูรณ์
Sycorax พูดว่า Reinstate Monica

@GeneralAbrial ใช่นี่คือสิ่งที่ฉันทำไปแล้ว ขออภัยในความสับสนฉันพยายามเก็บคำถามในโหมดเชิงทฤษฎีมากกว่าการพัฒนา
mobius

คุณช่วยเพิ่มรหัสของคุณที่นี่ได้ไหม คุณใช้ sample_weight = "balance" สำหรับ SGD เป็นพิเศษหรือไม่ แต่อาจมีสิ่งอื่น ๆ ที่ควรทราบเมื่อเราเห็นรหัสของคุณ
Diego

คำตอบ:


21

ความแม่นยำของเซตย่อยเป็นตัวชี้วัดที่รุนแรง เพื่อให้เข้าใจว่าดีหรือไม่ดี 0.29 มีความคิด:

  • ดูจำนวนฉลากที่คุณมีค่าเฉลี่ยสำหรับแต่ละตัวอย่าง
  • ดูข้อตกลงระหว่างผู้จดบันทึกถ้ามี (ถ้าไม่ลองด้วยตัวคุณเองเพื่อดูความแม่นยำของเซตย่อยที่ได้รับเมื่อคุณเป็นตัวจําแนก)
  • คิดว่าหัวข้อที่กำหนดไว้ดี
  • ดูจำนวนตัวอย่างที่คุณมีสำหรับแต่ละป้ายกำกับ

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

ในเวลาเดียวกันจากสิ่งที่ฉันเข้าใจว่าฉันไม่สามารถใช้ scikit.metrics กับ OneVsRestClassifier ดังนั้นฉันจะได้รับตัวชี้วัด (F1, Precision, Recall และอื่น ๆ ) เพื่อหาว่ามีอะไรผิดปกติได้อย่างไร

ดูวิธีการคำนวณความแม่นยำ / การเรียกคืนสำหรับการจำแนกประเภทหลายคลาสแบบมัลติลาเบล . ฉันลืมว่า sklearn สนับสนุนผมจำได้ว่ามีข้อ จำกัด บางอย่างเช่นsklearn ไม่สนับสนุนหลายป้ายสับสนเมทริกซ์ นั่นเป็นความคิดที่ดีที่จะเห็นตัวเลขเหล่านี้แน่นอน


คะแนน Hamming :

ในการตั้งค่าการจำแนกหมวดหมู่แบบหลายฉลากsklearn.metrics.accuracy_scoreเพียงคำนวณความแม่นยำของชุดย่อย (3): เช่นชุดของฉลากที่คาดการณ์ไว้สำหรับตัวอย่างจะต้องตรงกับชุดของฉลากที่เกี่ยวข้องใน y_true

บางครั้งวิธีการคำนวณความแม่นยำนี้มีชื่อว่าบางครั้งอาจมีอัตราส่วนการจับคู่ที่ไม่ชัดเจน(1):

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

อีกวิธีโดยทั่วไปในการคำนวณความถูกต้องถูกกำหนดไว้ใน (1) และ (2) และน้อยเลศนัยเรียกว่าคะแนน Hamming (4) (เพราะมันเป็นเรื่องที่เกี่ยวข้องอย่างใกล้ชิดกับการสูญเสีย Hamming) หรือฉลากตามความถูกต้อง ) คำนวณได้ดังนี้

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

นี่คือวิธีไพ ธ อนในการคำนวณคะแนน Hamming:

# Code by /programming//users/1953100/william
# Source: /programming//a/32239764/395857
# License: cc by-sa 3.0 with attribution required

import numpy as np

y_true = np.array([[0,1,0],
                   [0,1,1],
                   [1,0,1],
                   [0,0,1]])

y_pred = np.array([[0,1,1],
                   [0,1,1],
                   [0,1,0],
                   [0,0,0]])

def hamming_score(y_true, y_pred, normalize=True, sample_weight=None):
    '''
    Compute the Hamming score (a.k.a. label-based accuracy) for the multi-label case
    /programming//q/32239577/395857
    '''
    acc_list = []
    for i in range(y_true.shape[0]):
        set_true = set( np.where(y_true[i])[0] )
        set_pred = set( np.where(y_pred[i])[0] )
        #print('\nset_true: {0}'.format(set_true))
        #print('set_pred: {0}'.format(set_pred))
        tmp_a = None
        if len(set_true) == 0 and len(set_pred) == 0:
            tmp_a = 1
        else:
            tmp_a = len(set_true.intersection(set_pred))/\
                    float( len(set_true.union(set_pred)) )
        #print('tmp_a: {0}'.format(tmp_a))
        acc_list.append(tmp_a)
    return np.mean(acc_list)

if __name__ == "__main__":
    print('Hamming score: {0}'.format(hamming_score(y_true, y_pred))) # 0.375 (= (0.5+1+0+0)/4)

    # For comparison sake:
    import sklearn.metrics

    # Subset accuracy
    # 0.25 (= 0+1+0+0 / 4) --> 1 if the prediction for one sample fully matches the gold. 0 otherwise.
    print('Subset accuracy: {0}'.format(sklearn.metrics.accuracy_score(y_true, y_pred, normalize=True, sample_weight=None)))

    # Hamming loss (smaller is better)
    # $$ \text{HammingLoss}(x_i, y_i) = \frac{1}{|D|} \sum_{i=1}^{|D|} \frac{xor(x_i, y_i)}{|L|}, $$
    # where
    #  - \\(|D|\\) is the number of samples  
    #  - \\(|L|\\) is the number of labels  
    #  - \\(y_i\\) is the ground truth  
    #  - \\(x_i\\)  is the prediction.  
    # 0.416666666667 (= (1+0+3+1) / (3*4) )
    print('Hamming loss: {0}'.format(sklearn.metrics.hamming_loss(y_true, y_pred))) 

ขาออก:

Hamming score: 0.375
Subset accuracy: 0.25
Hamming loss: 0.416666666667

(1) Sorower, Mohammad S. " การสำรวจวรรณกรรมเกี่ยวกับอัลกอริทึมสำหรับการเรียนรู้แบบหลายฉลาก " Oregon State University, Corvallis (2010)

(2) Tsoumakas, Grigorios และ Ioannis Katakis " การจัดหมวดหมู่หลายฉลาก: ภาพรวม " ฝ่ายเทคโนโลยีสารสนเทศมหาวิทยาลัย Aristotle of Thessaloniki, กรีซ (2006)

(3) Ghamrawi, Nadia และ Andrew McCallum " การจำแนกหลายหมวดหมู่โดยรวม " การดำเนินการประชุมนานาชาติ ACM ครั้งที่ 14 เรื่องการจัดการข้อมูลและความรู้ ACM, 2005

(4) Godbole, Shantanu และ Sunita Sarawagi " วิธีการจำแนกสำหรับการจำแนกประเภทที่มีหลายป้ายกำกับ " ความก้าวหน้าในการค้นหาความรู้และการทำเหมืองข้อมูล Springer Berlin Heidelberg, 2004. 22-30.


คำตอบที่ดีมันทำให้ฉันดีขึ้น :) ฉันจะอ่านให้ละเอียดยิ่งขึ้นลองใช้คะแนน Hamming และกลับไปหาคุณ!
mobius

ความจริงแล้วมันไม่ชัดเจนสำหรับฉันเลยว่าความแม่นยำของเซตย่อย (Exact Match Ratio) คืออะไร คุณช่วยอธิบายเพิ่มเติมอีกหน่อยได้ไหม ดูเหมือนว่าในกรณีของมัลติคลาสจะเหมือนกับการเรียกคืน
Poete Maudit

hamming_scoreข้อผิดพลาดการทำงานออกใน Keras: <ipython อินพุต-34-16066d66dfdd> ใน hamming_score (y_true, y_pred ปกติ, sample_weight) 60 ''' 61 acc_list = [] ---> 62 สำหรับฉันในช่วง (y_true.shape [ 0]): 63 set_true = set (np.where (y_true [i]) [0]) 64 set_pred = set (np.where (y_pred [i]) [0] TypeError: ดัชนีคืนค่า non-int (ประเภท NoneType )
rjurney

0

คะแนน 0.29 ไม่เพียงพอหรือไม่ เมทริกซ์ความสับสนของคุณมีลักษณะอย่างไร มีบางหัวข้อที่ไม่สามารถแยกออกได้โดยดูจากเนื้อหาคำเท่านั้นหรือไม่

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

ในการทดสอบสมมติฐานนี้คุณต้องมีชุดเอกสารทดสอบที่มีคุณสมบัติเป็นคำที่รู้จัก (ซึ่งคุณสร้างขึ้นเอง) คุณควรได้รับคะแนน 100%

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


นอกเหนือจากตัวเลขที่ฉันรู้สึกว่า 0.29 อยู่ในระดับต่ำ ฉันใช้แบบจำลองที่ได้รับการฝึกอบรมเพื่อทำนายหัวข้อในเอกสารที่ฉันใช้ไปแล้วในการฝึกอบรมเพื่อทดสอบตัวจําแนกด้วยตนเอง ฉันไม่สามารถรับหัวข้ออย่างน้อยจำนวนเดียวกันกับที่ผู้ใช้ป้อนด้วยตนเองในเอกสาร ฉันมักจะได้รับส่วนหนึ่งของพวกเขา นอกจากนี้สำหรับคำถามเกี่ยวกับความสับสนฉันไม่คิดว่าฉันจะได้รับความสับสนใน OneVsRestClassifier โดยใช้ scikit.metrics ... ฉันจะตรวจสอบว่า
mobius
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.