Çok sınıflı veri kümesinde yanlış sınıflandırmaya neden olan dengesiz veriler


9

39 kategori / sınıf ve 8.5 milyon kaydım olan metin sınıflandırması üzerinde çalışıyorum. (Gelecekte veri ve kategoriler artacaktır).

Verilerimin yapısı veya biçimi aşağıdaki gibidir.

----------------------------------------------------------------------------------------
| 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  

Veri dağıtımı normal değildir; oldukça dengesizdir:

-------------------------
| 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       

Gördüğünüz gibi, oldukça dengesiz ve yanlış sınıflandırmalara yol açıyorlar.

Şimdiye kadar gerçekleştirdiğim adımlar

1) product_title ve key_value_pairs sütunlarını birleştirin ve durdurma sözcüklerini ve özel karakterleri kaldırın ve stemming yapın.

2) TFIDFvectorizer (), LinearSVC () için boru hattı kullandım

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

Bundan sonra boru hattına uydum ve sınıflandırıcıyı turşu içinde sakladım

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

Test tarafında, yukarıda belirtildiği gibi 1. adımı tekrarladım ve daha sonra turşu yükleyin ve tahmin fonksiyonunu kullanın

pd = cl.predict([testData])

Karşılaştığım sorunlar

  1. Birçok ürün diğer bazı kategorilerde yanlış sınıflandırılıyor

    Örnek: Ultimate Nutrition Prostar% 100 Whey Protein kategori 311 olarak sınıflandırılmalıdır, ancak sınıflandırıcım 222 olarak sınıflandırıyor ve bu tamamen yanlış.

  2. TFidfVectorizer () veya Hashingvectorizer () kullanıp kullanmadığından emin değilim, sizden parametrelerle birlikte bunlardan birini seçmeme yardımcı olabilir misiniz?

  3. Kullandığım algoritma LinearSVC, çok miktarda veri içeren çok sınıflı sınıflandırma problemleri için iyi bir seçim mi? Yoksa farklı algoritmalar mı kullanmalıyım?

  4. Verilerim dengesiz olduğundan rastgele örnekleme denedim. Sonuçlar düzeldi, ancak hala işarete kadar değildi. Ayrıca bu rastgele örnekleme gerçekleştirmek için doğru bir yaklaşım olup olmadığından emin değilim:

    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. Makine öğreniminde yeniyim, bu yüzden metin yaklaşımı için bu yaklaşımı kullandım. Yaklaşımım yanlışsa, lütfen beni doğru olanla düzeltin.

(Daha iyi anlamama yardımcı olacağı için örneklerle öneri veya çözüm verirseniz harika olur).

*** DÜZENLEME-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)

Az örneklemeyi denediğini gördüm. Sadece fyi, Sci-Kit Learn'de Startified K-fold çapraz doğrulaması da sınıf dağılımını dikkate alıyor.
Kasra Manshaei

Yanıtlar:


6

Güzel soru!

Bazı Açıklamalar

Dengesiz veriler için farklı yaklaşımlarınız vardır. En köklü olanı yeniden örnekleme (Küçük sınıfları fazla örnekleme / büyük sınıfları az örnekleme ). Diğeri, sınıflandırmanızı hiyerarşik hale getirmek, yani büyük sınıfları diğerlerine karşı sınıflandırmak ve daha sonra ikinci sınıfta küçük sınıfları sınıflandırmaktır (sınıflandırıcıların aynı olması gerekmez. En iyisini bulmak için model seçim stratejilerini deneyin).

Pratik Cevap

Verileri yeniden örneklemeden kabul edilebilir sonuçlar aldım! Bu yüzden deneyin ama daha sonra yeniden örnekleme yöntemleri kullanarak geliştirin (istatistiksel olarak tür bir zorunluluktur).

TFIDF böyle bir sorun için iyidir. Sınıflandırıcılar model seçimi ile seçilmelidir, ancak deneyimlerim Lojistik Regresyon ve Rastgele Orman'ın bu özel problem üzerinde iyi çalıştığını göstermektedir (ancak bu sadece pratik bir deneyimdir).

Sadece iyi çalıştığı için aşağıdaki kodu takip edebilirsiniz, o zaman sonuçlarınızı iyileştirmek için değiştirmeyi deneyebilirsiniz:

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]

Kodun soyut olduğunu lütfen unutmayın; bu nedenle TianX, TrainY, TestX, vb. Sizin tarafınızdan doğru şekilde tanımlanmalıdır.

İpuçları

StopWord'un ne olduğuna dikkat edin. Pratikte birçok kişi (ben dahil!), Önceden tanımlanmış listelere göre durma kelimelerini kaldırmak için bu hatayı yaptı. Bu doğru değil!

Stop kelimeleri corpus duyarlıdır, bu yüzden bilgi teorik kavramlarına göre stopwords kaldırmanız gerekir (basit tutmak için, TFIDF türünün corpus'a özgü stopwords'lerinizi yok sayar. Daha fazla açıklamaya ihtiyacınız varsa lütfen cevabımı güncellememi bildirin) .

VotingClassifier, Ensemble Methods ailesinde bir meta öğrenme stratejisidir . Farklı sınıflandırıcılardan faydalanırlar. Pratikte oldukça iyi çalıştıkça onları deneyin.

Oylama şeması sadece farklı sınıflandırıcıların sonuçlarını alır ve doğru olma olasılığı en yüksek olanın çıktısını verir. Diktatörlüğe karşı böyle bir demokratik yaklaşım;)

Umarım yardımcı olur!


Hoşgeldiniz! Sezgisel yeniden örnekleme için yeniden örnekleme için koyduğum bağlantıya başvurabilirsiniz. Adım adım talimat var.
Kasra Manshaei

Çözümünüzü deniyorum, eğer herhangi bir yere sıkışmışsam veya herhangi bir şüphe durumunda yorum bölümünde göndereceğim. umarım bu senin için iyi olur!
aykırı

emin arkadaşım ... iyi şanslar!
Kasra Manshaei

1
Eğer işe yaradıysa cevabı kabul edebilirsiniz :)
Kasra Manshaei

@outlier sorunun cevabını ele aldığından, lütfen kabul edin (ve muhtemelen oy verin); yanıtları (gönüllü) yanıtlayanlar için değerli zaman alıyor
desertnaut
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.