ข้อมูลที่ไม่สมดุลทำให้เกิดการจำแนกผิดพลาดในชุดข้อมูลหลายคลาส


9

ฉันทำงานเกี่ยวกับการจำแนกข้อความที่ฉันมี 39 หมวดหมู่ / คลาสและ 8.5 ล้านบันทึก (ในอนาคตข้อมูลและหมวดหมู่จะเพิ่มขึ้น)

โครงสร้างหรือรูปแบบของข้อมูลของฉันมีดังนี้

----------------------------------------------------------------------------------------
| product_title          | Key_value_pairs                               | taxonomy_id |
----------------------------------------------------------------------------------------
  Samsung S7 Edge        | Color:black,Display Size:5.5 inch,Internal    | 211 
                          Storage:128 GB, RAM:4 GB,Primary Camera:12 MP  

  Case cover Honor 8     | Color:transparent,Height:15 mm,width:22 mm    | 212 

  Ruggers Men's T-Shirt  | Size:L,ideal for:men,fit:regular,             | 111
                          sleeve:half sleeve

  Optimum Nutrition Gold | Flavor:chocolate,form:powder,size:34 gm       | 311
  Standard Whey Protein  

การกระจายข้อมูลไม่ปกติ มันไม่สมดุลอย่างมาก:

-------------------------
| taxonomy_id |   count |
-------------------------
          111 |  851750 
          112 |  355592
          113 |  379433
          114 |   23138
          115 |  117735
          116 |  145757
          117 | 1339471
          121 |  394026
          122 |  193433
          123 |   78299
          124 |  111962
          131 |    1776
          132 |    4425
          133 |     908
          134 |   23062
          141 |   22713
          142 |   42073
          211 |    7892
          212 | 1574744
          221 |    1047
          222 |  397515
          223 |   53009
          231 |    1227
          232 |    7683
          251 |     739
          252 |     327
          253 |   38974
          254 |      25
          311 |    2901
          321 |    7126
          412 |     856
          421 |  697802
          422 |  414855
          423 |   17750
          425 |    1240
          427 |     658
          429 |    1058
          431 |   20760
          441 |     257       

ในขณะที่คุณสามารถเห็นพวกเขามีความสมดุลสูงและนำไปสู่การจำแนกผิดพลาด

ขั้นตอนที่ฉันได้ดำเนินการจนถึงตอนนี้

1) ผสานคอลัมน์ product_title และ key_value_pairs และลบคำหยุดและอักขระพิเศษและทำการหยุดการทำงาน

2) ฉันได้ใช้ไปป์ไลน์สำหรับ TFIDFvectorizer (), LinearSVC ()

vectorizerPipe = Pipeline([
                 ('tfidf', TfidfVectorizer(lowercase=True, stop_words='english')),
                 ('classification', OneVsRestClassifier(LinearSVC(penalty='l2', loss='hinge'))),
                 ])

หลังจากนี้ฉันมีท่อที่เหมาะสมและเก็บลักษณนามในดอง

prd = vectorizerPipe.fit(df.loc[:, 'description'], df.loc[:, 'taxonomy_id'])

ในด้านการทดสอบฉันได้ทำซ้ำขั้นตอนที่ 1 ดังกล่าวข้างต้นแล้วโหลดดองและใช้ฟังก์ชั่นการทำนาย

pd = cl.predict([testData])

ปัญหาที่ฉันกำลังเผชิญ

  1. ผลิตภัณฑ์จำนวนมากถูกจัดประเภทผิดประเภท

    ตัวอย่าง: Ultimate Nutrition Prostar 100% Whey Protein ควรแบ่งออกเป็นหมวดหมู่ 311 แต่ตัวจําแนกของฉันแบ่งเป็น 222 ซึ่งผิดทั้งหมด

  2. ฉันไม่แน่ใจว่าจะใช้ TFidfVectorizer () หรือ Hashingvectorizer () พวกคุณช่วยฉันเลือกหนึ่งในนี้พร้อมกับพารามิเตอร์ได้หรือไม่?

  3. อัลกอริทึมที่ฉันใช้เป็น LinearSVC เป็นตัวเลือกที่ดีสำหรับปัญหาการจำแนกประเภทหลายคลาสที่มีข้อมูลจำนวนมากหรือไม่? หรือฉันควรใช้อัลกอริทึมที่แตกต่างกันอย่างไร

  4. เนื่องจากข้อมูลของฉันมีความไม่สมดุลสูงฉันจึงลองสุ่มตัวอย่างแบบสุ่ม ผลลัพธ์ได้รับการปรับปรุง แต่ก็ยังไม่ถึงมาตรฐาน นอกจากนี้ฉันไม่แน่ใจว่านี่เป็นวิธีการที่เหมาะสมในการทำการสุ่มตัวอย่างแบบสุ่มหรือไม่:

    pipe = make_pipeline_imb(
        HashingVectorizer(lowercase=True),
        RandomUnderSampler(ratio={111: 405805, 112: 170431, 113: 241709, 114: 8341, 115: 50328, 116: 89445, 117: 650020, 121: 320803, 122: 162557, 123: 66156, 124: 36276, 131: 1196, 132: 3365, 133: 818, 134: 15001, 141: 6145, 142: 31783, 211: 24728, 212: 100000, 221: 791, 222: 8000, 223: 35406, 231: 785, 232: 3000, 251: 477, 252: 127, 253: 29563, 254: 33, 311: 2072, 321: 5370, 412: 652, 421: 520973, 422: 99171, 423: 16786, 425: 730, 427: 198, 429: 1249, 431: 13793, 441: 160},random_state=1), 
        OneVsRestClassifier(LinearSVC(penalty='l2', loss='hinge')))
    
  5. ฉันใหม่ในการเรียนรู้ของเครื่องดังนั้นฉันจึงใช้วิธีนี้สำหรับการจำแนกข้อความ หากวิธีการของฉันไม่ถูกต้องโปรดแก้ไขฉันด้วยวิธีที่ถูกต้อง

(มันจะดีมากถ้าคุณให้คำแนะนำหรือวิธีแก้ปัญหาพร้อมตัวอย่างเพราะมันจะช่วยให้ฉันเข้าใจได้ดีขึ้น)

*** แก้ไข-1 ****

RndmFrst = RandomForestClassifier(n_estimators=100, max_depth=20, max_features=5000,n_jobs=-1)
LogReg = LogisticRegression()
voting = VotingClassifier(estimators=[('LogReg ', LogReg), ('RndmFrst', RndmFrst)], voting='soft', n_jobs=-1)

pipe = Pipeline([('tfidf', TfidfVectorizer(ngram_range=(1,4), max_features=50000)), ('clf', voting)])

pipe = pipe.fit(df.loc[:,'description'], df.loc[:,'taxonomy_id'])
Preds = pipe.predict(test_data)

ฉันเพิ่งเห็นว่าคุณลองสุ่มตัวอย่าง เพียงแค่ fyi การตรวจสอบความถูกต้องข้ามแบบ K-fold ใน Sci-Kit Learn ยังคำนึงถึงการกระจายคลาสด้วย
Kasra Manshaei

คำตอบ:


6

เป็นคำถามที่ดี!

ข้อสังเกตบางส่วน

สำหรับข้อมูลที่ไม่สมดุลคุณมีวิธีการต่างกัน ส่วนใหญ่ที่ยอมรับกันดีคือresampling (Oversampling คลาสเล็ก / underssampling คลาสขนาดใหญ่) อีกประเภทหนึ่งคือการจัดลำดับชั้นการจำแนกประเภทของคุณเช่นการจำแนกคลาสขนาดใหญ่กับคลาสอื่น ๆ ทั้งหมดจากนั้นแยกประเภทคลาสย่อยในขั้นตอนที่สอง

คำตอบการปฏิบัติ

ฉันได้ผลลัพธ์ที่ยอมรับได้โดยไม่ต้องสุ่มข้อมูลใหม่อีกครั้ง! ดังนั้นลองใช้ แต่ปรับปรุงในภายหลังโดยใช้วิธีการสุ่มตัวอย่างใหม่ (ในเชิงสถิติพวกเขาเป็นแบบ A ต้อง)

TFIDF นั้นดีสำหรับปัญหาดังกล่าว ควรเลือกตัวแยกประเภทผ่านการเลือกแบบจำลอง แต่ประสบการณ์ของฉันแสดงว่า Logistic Regression และ Random Forest ทำงานได้ดีกับปัญหาเฉพาะนี้ (แต่เป็นเพียงประสบการณ์เชิงปฏิบัติ)

คุณอาจปฏิบัติตามรหัสตะโกนในขณะที่มันใช้งานได้ดีแล้วคุณอาจลองแก้ไขมันเพื่อปรับปรุงผลลัพธ์ของคุณ:

train = pd.read_csv(...)
test = pd.read_csv(...)    

# TFIDF Bag Of Words Model For Text Curpos. Up to 4-grams and 50k Features
vec = TfidfVectorizer(ngram_range=(1,4), max_features=50000)
TrainX = vec.fit_transform(train)
TestX = vec.transform(test)


# Initializing Base Estimators
clf1 = LogisticRegression()
clf2 = RandomForestClassifier(n_estimators=100, max_depth=20, max_features=5000,n_jobs=-1)

# Soft Voting Classifier For Each Column
clf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2)], voting='soft', n_jobs=-1)
clf = clf.fit(TrainX, TrainY)
preds = clf.predict_proba(TestX)[:,1]

โปรดทราบว่ารหัสนั้นเป็นนามธรรมดังนั้น TianX, TrainY, TestX และอื่น ๆ ควรได้รับการกำหนดอย่างถูกต้องจากคุณ

คำแนะนำ

ระวังเกี่ยวกับ StopWord คืออะไร หลายคนในทางปฏิบัติ (รวมถึงตัวฉันด้วย!) ทำผิดนี้เพื่อลบคำหยุดตามรายการที่กำหนดไว้ล่วงหน้า ไม่ถูกต้อง!

(เพื่อให้ง่ายคุณจำเป็นต้องรู้ TFIDF ชนิดที่ไม่สนใจ stopwords เฉพาะคลังของคุณหากคุณต้องการคำอธิบายเพิ่มเติมกรุณาแจ้งให้เราทราบเพื่อปรับปรุงคำตอบของฉัน) .

VotingClassifier เป็นกลยุทธ์ที่เมตาการเรียนรู้ในครอบครัวของวิธีทั้งมวล พวกเขาใช้ประโยชน์จากตัวแยกประเภทที่แตกต่างกัน ลองใช้งานเพราะฝึกซ้อมได้ดี

สคีมาของการลงคะแนนนั้นใช้ผลลัพธ์ของตัวแยกประเภทที่แตกต่างกันและคืนเอาต์พุตของอันที่มีความน่าจะเป็นสูงสุด วิธีการแบบประชาธิปไตยในการต่อต้านเผด็จการ;)

หวังว่ามันจะช่วย!


ยินดีต้อนรับ! สำหรับการ resampling ที่ใช้งานง่ายคุณสามารถดูลิงค์ที่ฉันใส่เพื่อ resampling มีคำแนะนำทีละขั้นตอน
Kasra Manshaei

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

แน่ใจว่าเพื่อนของฉัน ... โชคดี!
Kasra Manshaei

1
ถ้าใช้งานได้คุณอาจยอมรับคำตอบได้ :)
Kasra Manshaei

@ ก่อนหน้านี้เนื่องจากคำตอบได้แก้ไขปัญหาของคุณแล้วโปรดยอมรับ (และอาจเป็น upvote) คำตอบใช้เวลาอันมีค่าสำหรับผู้ตอบแบบสอบถาม (อาสาสมัคร)
Desertnaut
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.