Pracuję nad klasyfikacją tekstu, w której mam 39 kategorii / klas i 8,5 miliona rekordów. (W przyszłości dane i kategorie wzrosną).
Struktura lub format moich danych jest następująca.
----------------------------------------------------------------------------------------
| 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
Dystrybucja danych nie jest normalna; jest wysoce niezrównoważony:
-------------------------
| 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
Jak widać, są one wysoce niezrównoważone i prowadzą do błędnej klasyfikacji.
Kroki, które wykonałem do tej pory
1) Scal kolumnę product_title i key_value_pairs i usuń słowa stop oraz znaki specjalne i wykonaj tworzenie.
2) Użyłem potoku dla TFIDFvectorizer (), LinearSVC ()
vectorizerPipe = Pipeline([
('tfidf', TfidfVectorizer(lowercase=True, stop_words='english')),
('classification', OneVsRestClassifier(LinearSVC(penalty='l2', loss='hinge'))),
])
Następnie dopasowałem rurociąg i umieściłem klasyfikator w marynacie
prd = vectorizerPipe.fit(df.loc[:, 'description'], df.loc[:, 'taxonomy_id'])
Po stronie testowej powtórzyłem krok 1, jak wspomniano powyżej, a następnie załadowałem marynatę i użyj funkcji przewidywania
pd = cl.predict([testData])
Problemy, przed którymi stoję
Wiele produktów jest błędnie klasyfikowanych do niektórych innych kategorii
Przykład: Ultimate Nutrition Prostar 100% białko serwatki należy zaklasyfikować do kategorii 311, ale mój klasyfikator klasyfikuje je jako 222, co jest całkowicie błędne.
Nie jestem pewien, czy użyć TFidfVectorizer () czy Hashingvectorizer (), czy możecie mi pomóc w wyborze jednego z nich wraz z ich parametrami?
Algorytm, którego używam, to LinearSVC, czy to dobry wybór w przypadku problemów z klasyfikacją wielu klas z dużą ilością danych? Czy powinienem używać różnych algorytmów?
Ponieważ moje dane są wysoce niezrównoważone, próbowałem losowego testowania próbkowania. Wyniki uległy poprawie, ale nadal nie były na granicy. Nie jestem również pewien, czy jest to właściwe podejście do losowego niepełnego próbkowania:
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')))
Jestem nowy w uczeniu maszynowym, więc zastosowałem to podejście do klasyfikacji tekstu. Jeśli moje podejście jest błędne, popraw mnie, używając właściwego.
(Byłoby wspaniale, gdybyś podał sugestię lub rozwiązanie z przykładami, ponieważ pomoże mi to lepiej zrozumieć).
*** 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)
Odpowiedzi:
Dobre pytanie!
Kilka uwag
W przypadku niezrównoważonych danych masz różne podejścia. Najbardziej ugruntowaną jest ponowne próbkowanie (nadmierne próbkowanie małych klas / niedoszacowywanie dużych klas). Drugim jest zhierarchizowanie klasyfikacji, tj. Sklasyfikowanie dużych klas względem wszystkich innych, a następnie sklasyfikowanie małych klas w drugim etapie (klasyfikatory nie powinny być takie same. Spróbuj znaleźć strategie wyboru modelu, aby znaleźć najlepszą).
Praktyczna odpowiedź
Mam akceptowalne wyniki bez ponownego próbkowania danych! Spróbuj, ale później popraw go za pomocą metod ponownego próbkowania (statystycznie MUSZĄ to być).
TFIDF jest dobry na taki problem. Klasyfikatory powinny być wybierane poprzez wybór modelu, ale moje doświadczenie pokazuje, że regresja logistyczna i losowy las działają dobrze na ten konkretny problem (jednak jest to tylko praktyczne doświadczenie).
Możesz postępować zgodnie z poniższym kodem, ponieważ działał on po prostu dobrze, a następnie możesz go zmodyfikować, aby poprawić swoje wyniki:
Pamiętaj, że kod jest abstrakcyjny, więc TianX, TrainY, TestX itp. Powinny być poprawnie zdefiniowane przez Ciebie.
Poradnik
Uważaj na to, co jest StopWord. Praktycznie wiele osób (w tym ja!) Popełniło ten błąd, usuwając słowa stop zgodnie z wcześniej zdefiniowanymi listami. To nie jest poprawne!
Słowa stop są wrażliwe na korpusy, więc musisz usunąć stopery zgodnie z teoretycznymi pojęciami informacyjnymi (dla uproszczenia musisz wiedzieć, że TFIDF ignoruje specyficzne dla korpusu hasła. Jeśli potrzebujesz więcej wyjaśnień, daj mi znać, aby zaktualizować moją odpowiedź) .
VotingClassifier to strategia meta-uczenia się w rodzinie Ensemble Methods . Korzystają z różnych klasyfikatorów. Wypróbuj je, ponieważ sprawdzają się w praktyce.
Schemat głosowania po prostu bierze wyniki różnych klasyfikatorów i zwraca wynik tego, który ma największe prawdopodobieństwo, że ma rację. Takie rodzaj demokratycznego podejścia przeciwko dyktaturze;)
Mam nadzieję, że to pomoże!
źródło