Unausgeglichene Daten, die zu einer Fehlklassifizierung des Datensatzes mit mehreren Klassen führen

9

Ich arbeite an einer Textklassifizierung mit 39 Kategorien / Klassen und 8,5 Millionen Datensätzen. (In Zukunft werden Daten und Kategorien zunehmen).

Struktur oder Format meiner Daten ist wie folgt.

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

Die Datenverteilung ist nicht normal. es ist sehr unausgeglichen:

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

Wie Sie sehen, sind sie sehr unausgewogen und führen zu Fehlklassifizierungen.

Schritte, die ich bis jetzt ausgeführt habe

1) Führen Sie die Spalten product_title und key_value_pairs zusammen, entfernen Sie Stoppwörter und Sonderzeichen und führen Sie das Stemming durch.

2) Ich habe eine Pipeline für TFIDFvectorizer (), LinearSVC () verwendet.

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

Danach habe ich die Pipeline angepasst und den Klassifikator in pickle gespeichert

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

Auf der Testseite habe ich Schritt 1 wie oben erwähnt wiederholt und dann die Gurke geladen und die Vorhersagefunktion verwendet

pd = cl.predict([testData])

Probleme, mit denen ich konfrontiert bin

  1. Viele Produkte werden in einige andere Kategorien falsch eingeteilt

    Beispiel: Ultimate Nutrition Prostar 100% Whey Protein sollte in Kategorie 311 eingestuft werden, aber mein Klassifikator klassifiziert es als 222, was völlig falsch ist.

  2. Ich bin mir nicht sicher, ob ich TFidfVectorizer () oder Hashingvectorizer () verwenden soll. Könnt ihr mir bei der Auswahl eines dieser Elemente zusammen mit ihren Parametern helfen?

  3. Der von mir verwendete Algorithmus ist LinearSVC. Ist er eine gute Wahl für Probleme bei der Klassifizierung mehrerer Klassen mit großen Datenmengen? Oder sollte ich andere Algorithmen verwenden?

  4. Da meine Daten sehr unausgewogen sind, habe ich versucht, eine zufällige Unterabtastung durchzuführen. Die Ergebnisse wurden verbessert, aber sie entsprachen immer noch nicht der Marke. Ich bin mir auch nicht sicher, ob dies der richtige Ansatz ist, um eine zufällige Unterabtastung durchzuführen:

    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. Ich bin neu im maschinellen Lernen und habe diesen Ansatz für die Textklassifizierung verwendet. Wenn mein Ansatz falsch ist, korrigieren Sie mich bitte mit dem richtigen.

(Es wäre großartig, wenn Sie Vorschläge oder Lösungen mit Beispielen geben würden, da dies mir hilft, besser zu verstehen).

*** EDIT-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)
Ausreißer
quelle
Ich habe gerade gesehen, dass Sie versucht haben, zu wenig Proben zu nehmen. Nur zu Ihrer Information, die Startified K-Fold-Kreuzvalidierung in Sci-Kit Learn berücksichtigt auch die Klassenverteilung.
Kasra Manshaei

Antworten:

6

Gute Frage!

Einige Bemerkungen

Für unausgeglichene Daten haben Sie unterschiedliche Ansätze. Am etabliertesten ist das Resampling (Überabtastung kleiner Klassen / Unterabtastung großer Klassen). Die andere besteht darin, Ihre Klassifizierung hierarchisch zu gestalten, dh große Klassen gegen alle anderen zu klassifizieren und dann kleine Klassen im zweiten Schritt zu klassifizieren (Klassifizierer sollten nicht gleich sein. Versuchen Sie Modellauswahlstrategien, um die besten zu finden).

Praktische Antwort

Ich habe akzeptable Ergebnisse erzielt, ohne die Daten erneut abzutasten! Probieren Sie es aus, aber verbessern Sie es später mithilfe von Resampling-Methoden (statistisch gesehen sind sie ein MUSS).

TFIDF ist gut für ein solches Problem. Klassifikatoren sollten durch Modellauswahl ausgewählt werden, aber meine Erfahrung zeigt, dass logistische Regression und Random Forest bei diesem spezifischen Problem gut funktionieren (es ist jedoch nur eine praktische Erfahrung).

Sie können dem folgenden Code folgen, da er einfach gut funktioniert hat. Dann können Sie versuchen, ihn zu ändern, um Ihre Ergebnisse zu verbessern:

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]

Bitte beachten Sie, dass der Code abstrakt ist, sodass TianX, TrainY, TestX usw. von Ihnen ordnungsgemäß definiert werden sollten.

Hinweise

Seien Sie vorsichtig mit StopWord. Praktisch viele Leute (einschließlich ich!) Haben diesen Fehler gemacht, Stoppwörter gemäß vordefinierter Listen zu entfernen. Das ist nicht richtig!

Stoppwörter sind korpussensitiv, daher müssen Sie Stoppwörter gemäß informationstheoretischen Konzepten entfernen (um es einfach zu halten, müssen Sie wissen, dass TFIDF Ihre korpusspezifischen Stoppwörter ignoriert. Wenn Sie weitere Erklärungen benötigen, lassen Sie mich bitte wissen, um meine Antwort zu aktualisieren). .

VotingClassifier ist eine Meta-Lernstrategie aus der Familie der Ensemble-Methoden . Sie profitieren von verschiedenen Klassifikatoren. Probieren Sie sie aus, da sie in der Praxis ziemlich gut funktionieren.

Das Abstimmungsschema verwendet einfach die Ergebnisse verschiedener Klassifizierer und gibt die Ausgabe desjenigen zurück, der die höchste Wahrscheinlichkeit hat, richtig zu sein. So ein demokratischer Ansatz gegen die Diktatur;)

Ich hoffe es hilft!

Kasra Manshaei
quelle
Herzlich willkommen! Für ein intuitives Resampling können Sie auf den Link verweisen, den ich zum Resampling eingefügt habe. Es gibt eine Schritt-für-Schritt-Anleitung.
Kasra Manshaei
Ich versuche Ihre Lösung, wenn ich irgendwo stecken geblieben bin oder im Zweifelsfall werde ich im Kommentarbereich posten. hoffe das wird gut für dich!
Ausreißer
sicher mein Freund ... viel Glück!
Kasra Manshaei
1
Wenn es funktioniert hat, können Sie die Antwort akzeptieren :)
Kasra Manshaei
@outlier Da die Antwort Ihr Problem behoben hat, akzeptieren Sie es bitte (und stimmen Sie es möglicherweise ab). Antworten nehmen wertvolle Zeit für (freiwillige) Befragte in
Anspruch