Я работаю над классификацией текста, где у меня 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])
Проблемы, с которыми я сталкиваюсь
Многие продукты неправильно классифицированы по некоторым другим категориям.
Пример: Ultimate Nutrition Prostar 100% Whey Protein должен быть классифицирован как категория 311, но мой классификатор классифицирует его как 222, что совершенно неверно.
Я не уверен, использовать ли TFidfVectorizer () или Hashingvectorizer (). Можете ли вы, ребята, помочь мне выбрать один из них вместе с их параметрами?
Алгоритм, который я использую, - LinearSVC, это хороший выбор для многоклассовых задач классификации с большим объемом данных? Или я должен использовать разные алгоритмы?
Поскольку мои данные сильно несбалансированы, я попробовал случайную недостаточную выборку. Результаты были улучшены, но они все еще не были на должном уровне. Также я не уверен, является ли это правильным подходом для выполнения случайной недостаточной выборки:
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')))
Я новичок в машинном обучении, поэтому я использовал этот подход для классификации текста. Если мой подход неправильный, пожалуйста, поправьте меня с правильным.
(Было бы здорово, если вы дадите предложение или решение с примерами, так как это поможет мне лучше понять).
*** 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)
Ответы:
Хороший вопрос!
Некоторые замечания
Для несбалансированных данных у вас есть разные подходы. Наиболее хорошо создано одна передискретизация (передискретизации маленьких классов / underssampling больших классов). Другой - сделать вашу классификацию иерархической, то есть классифицировать большие классы по отношению ко всем остальным, а затем классифицировать маленькие классы на втором этапе (классификаторы не должны быть одинаковыми. Попробуйте стратегии выбора моделей, чтобы найти лучший).
Практический ответ
Я получил приемлемые результаты без пересчета данных! Так что попробуйте, но позже улучшите его, используя методы передискретизации (статистически они вроде ДОЛЖНЫ).
TFIDF хорош для такой проблемы. Классификаторы следует выбирать с помощью выбора модели, но мой опыт показывает, что Логистическая регрессия и Случайный лес хорошо работают над этой конкретной проблемой (однако это просто практический опыт).
Вы можете следовать приведенному ниже коду, поскольку он работал просто хорошо, тогда вы можете попробовать изменить его, чтобы улучшить свои результаты:
Обратите внимание, что код является абстрактным, поэтому вы должны правильно определить TianX, TrainY, TestX и т. Д.
Советы
Будьте осторожны с тем, что такое StopWord. Практически многие люди (в том числе и я!) Допустили эту ошибку, чтобы удалить стоп-слова в соответствии с заранее определенными списками. Это неправильно!
Стоп-слова чувствительны к корпусу, поэтому вам нужно удалить стоп-слова в соответствии с теориями теории информации (для простоты вам нужно знать, что TFIDF не учитывает ваши стоп-слова, характерные для корпуса. Если вам нужно больше объяснений, дайте мне знать, чтобы обновить мой ответ) ,
VotingClassifier - это стратегия метаобучения в семействе методов ансамбля . Они получают выгоду от разных классификаторов. Попробуйте их, так как они хорошо работают на практике.
Схема голосования просто берет результаты разных классификаторов и возвращает результат того, который имеет наибольшую вероятность быть правым. Так что вроде демократический подход против диктатуры;)
Надеюсь, поможет!
источник