Estou trabalhando na classificação de texto, onde tenho 39 categorias / classes e 8,5 milhões de registros. (No futuro, dados e categorias aumentarão).
Estrutura ou formato dos meus dados é o seguinte.
----------------------------------------------------------------------------------------
| 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
A distribuição de dados não é normal; é altamente desequilibrado:
-------------------------
| 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
Como você pode ver, eles são altamente desequilibrados e levam a erros de classificação.
Etapas que eu executei até agora
1) Mescle a coluna product_title e key_value_pairs e remova palavras de parada e caracteres especiais e execute a derivação.
2) Eu usei pipeline para TFIDFvectorizer (), LinearSVC ()
vectorizerPipe = Pipeline([
('tfidf', TfidfVectorizer(lowercase=True, stop_words='english')),
('classification', OneVsRestClassifier(LinearSVC(penalty='l2', loss='hinge'))),
])
Depois disso, ajustei o pipeline e guardei o classificador em picles
prd = vectorizerPipe.fit(df.loc[:, 'description'], df.loc[:, 'taxonomy_id'])
No lado do teste, repeti a etapa 1, conforme mencionado acima, e carregue o pickle e use a função de previsão
pd = cl.predict([testData])
Problemas que estou enfrentando
Muitos produtos estão sendo classificados incorretamente em algumas outras categorias
Exemplo: Ultimate Nutrition Prostar 100% Whey Protein deve ser classificado na categoria 311, mas meu classificador está classificando-o como 222, o que está completamente errado.
Não tenho certeza se devo usar o TFidfVectorizer () ou o Hashingvectorizer (), vocês podem me ajudar a selecionar uma dessas opções juntamente com os parâmetros?
O algoritmo que estou usando é o LinearSVC, é uma boa opção para problemas de classificação de várias classes com grande quantidade de dados? Ou devo usar algoritmos diferentes?
Como meus dados estão altamente desequilibrados, tentei uma subamostragem aleatória. Os resultados foram aprimorados, mas ainda não estavam à altura. Também não tenho certeza se esta é a abordagem correta para executar uma subamostragem aleatória:
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')))
Eu sou novo em aprendizado de máquina, então usei essa abordagem para classificação de texto. Se minha abordagem estiver errada, corrija-me com a correta.
(Seria ótimo se você der sugestões ou soluções com exemplos, pois isso me ajudará a entender melhor).
*** 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)
fonte
Respostas:
Boa pergunta!
Algumas observações
Para dados desequilibrados, você tem abordagens diferentes. O mais bem estabelecido é a reamostragem (sobreamostragem de pequenas classes / subamostragem de grandes classes). O outro é tornar sua classificação hierárquica, ou seja, classificar grandes classes contra todas as outras e depois classificar pequenas classes na segunda etapa (os classificadores não devem ser os mesmos. Tente estratégias de seleção de modelos para encontrar o melhor).
Resposta Prática
Eu tenho resultados aceitáveis sem reamostrar os dados! Portanto, tente, mas depois aprimore-o usando métodos de reamostragem (estatisticamente, eles são uma espécie de DEVE).
TFIDF é bom para esse problema. Os classificadores devem ser selecionados por meio da seleção de modelos, mas minha experiência mostra que a Regressão Logística e a Floresta Aleatória funcionam bem nesse problema específico (no entanto, é apenas uma experiência prática).
Você pode seguir o código abaixo, pois ele funcionou muito bem e tentar modificá-lo para melhorar seus resultados:
Observe que o código é abstrato, portanto, TianX, TrainY, TestX etc. devem ser adequadamente definidos por você.
Dicas
Tenha cuidado com o que é o StopWord. Praticamente muitas pessoas (inclusive eu!) Cometeram esse erro ao remover palavras de parada de acordo com listas predefinidas. Isso não está certo!
As palavras de parada são sensíveis ao corpus, portanto, você precisa remover as palavras de parada de acordo com os conceitos teóricos da informação (para simplificar, você precisa saber que o TFIDF ignora suas palavras de parada específicas do corpus. Se precisar de mais explicações, informe-me para atualizar minha resposta) .
VotingClassifier é uma estratégia de meta-aprendizado na família de Métodos de Conjunto . Eles se beneficiam de diferentes classificadores. Experimente-os, pois eles funcionam muito bem na prática.
O esquema de votação simplesmente pega os resultados de diferentes classificadores e retorna a saída daquele que tem a maior probabilidade de estar certo. Então, tipo de abordagem democrática contra a ditadura;)
Espero que ajude!
fonte