Повышение / понижение с одним против остальных классификатор - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть набор данных (взвешенные слова tf-idf) с несколькими классами, которые я пытаюсь предсказать.Мои занятия несбалансированы.Я хотел бы использовать подход классификации «один против остальных» с некоторыми классификаторами (например, с многозначным наивным байесовским), используя OneVsRestClassifier из sklearn.

Кроме того, я хотел бы использовать пакет imbalanced-learn (скорее всего, одну из комбинаций повышающей и понижающей дискретизации) для улучшения моих данных.Обычный подход использования imbalanced-learn:

from imblearn.combine import SMOTEENN
smote_enn = SMOTEENN(random_state=0)
X_resampled, y_resampled = smote_enn.fit_resample(X, y)

Теперь у меня есть набор данных с примерно одинаковым количеством случаев для каждой метки.Затем я использовал бы классификатор для данных с передискретизацией.

from sklearn.multiclass import OneVsRestClassifier
from sklearn.naive_bayes import MultinomialNB
ovr = OneVsRestClassifier(MultinomialNB())
ovr.fit(X_resampled, y_resampled)

Но: теперь существует огромный дисбаланс для каждой этикетки, когда она установлена, потому что у меня всего более 50 этикеток.Правильно?Я полагаю, что мне нужно применять метод повышения / понижения для каждого лейбла, а не делать это один раз в начале.Как я могу использовать пересчет для каждой метки?

1 Ответ

0 голосов
/ 30 ноября 2018

Согласно обсуждению в комментариях, то, что вы хотите, может быть сделано следующим образом:

from sklearn.naive_bayes import MultinomialNB
from imblearn.combine import SMOTEENN

# Observe how I imported Pipeline from IMBLEARN and not SKLEARN
from imblearn.pipeline import Pipeline
from sklearn.multiclass import OneVsRestClassifier

# This pipeline will resample the data and  
# pass the output to MultinomialNB
pipe = Pipeline([('sampl', SMOTEENN()), 
                 ('clf', MultinomialNB())])

# OVR will transform the `y` as you know and 
# then pass single label data to different copies of pipe 
# multiple times (as many labels in data)
ovr = OneVsRestClassifier(pipe)
ovr.fit(X, y)

Объяснение кода :

  • Шаг 1: OneVsRestClassifier создаст несколько столбцов y.Один для каждой метки, где эта метка положительная, а все остальные отрицательные.

  • Шаг 2: Для каждой метки OneVsRestClassifier будет клонировать предоставленную оценку pipe и передать отдельное лицоданные к нему.

  • Шаг 3:

    a.Каждая копия pipe получит отдельную версию y, которая передается в SMOTEENN внутри нее, и поэтому будет выполнять различную выборку, чтобы сбалансировать классы там.

    b.Вторая часть pipe (clf) получит тот сбалансированный набор данных для каждой метки, который вы хотели.

  • Шаг 4: Во время прогнозирования часть выборки будет отключенаТаким образом, данные достигнут clf как есть.Конвейер sklearn не обрабатывает эту часть, поэтому я использовал imblearn.pipeline.

Надеюсь, это поможет.

...