Подтвердить что ты не робот

Дисбаланс в scikit-learn

Я использую scikit-learn в своей программе Python для выполнения некоторых операций машинного обучения. Проблема в том, что мой набор данных имеет серьезные проблемы с дисбалансом.

Кто-нибудь знаком с решением проблемы дисбаланса в scikit-learn или в python вообще? В Java есть SMOTE-механизм. Есть что-то параллельное в python?

4b9b3361

Ответ 1

SMOTE не является встроенным в scikit-learn, но, тем не менее, есть онлайн-реализации.
Вот, к примеру.

Ответ 2

Здесь есть новый

https://github.com/scikit-learn-contrib/imbalanced-learn

Он содержит множество алгоритмов в следующих категориях, включая SMOTE

  • Недочет выборки класса большинства.
  • Чрезмерная выборка класса меньшинства.
  • Объединение избыточной и под выборки.
  • Создание ансамблевых сбалансированных наборов.

Ответ 3

В Scikit Learn есть несколько методов коррекции дисбаланса, которые варьируются в зависимости от того, какой алгоритм обучения вы используете.

Некоторые из них, такие как Svm или логистическая регрессия, имеют параметр class_weight. Если вы создаете экземпляр SVC с этим параметром, установленным на 'auto', он будет взвешивать каждый пример класса пропорционально частоте, обратной его.

К сожалению, для этой цели не существует препроцессорного инструмента.

Ответ 4

Здесь я нашел еще одну библиотеку, которая реализует заниженную выборку, а также несколько методов избыточной SMOTE включая несколько реализаций SMOTE и другую, которая использует SVM:

Пакет Python для преодоления проклятия несбалансированных наборов данных в машинном обучении

Ответ 5

Поскольку другие перечислили ссылки на очень популярную библиотеку imbalanced-learn, я дам обзор того, как правильно ее использовать, а также некоторые ссылки.

https://imbalanced-learn.org/en/stable/generated/imblearn.under_sampling.RandomUnderSampler.html

https://imbalanced-learn.org/en/stable/generated/imblearn.over_sampling.RandomOverSampler.html

https://imbalanced-learn.readthedocs.io/en/stable/generated/imblearn.over_sampling.SMOTE.html

https://imbalanced-learn.readthedocs.io/en/stable/auto_examples/over-sampling/plot_comparison_over_sampling.html#sphx-glr-auto-examples-over-sampling-plot-comparison-over-sampling-py

https://imbalanced-learn.org/en/stable/combine.html

В imbalanced-learning используются некоторые распространенные методы избыточной и недостаточной выборки: imblearn.over_sampling.RandomOverSampler, imblearn.under_sampling.RandomUnderSampler и imblearn.SMOTE. Для этих библиотек есть хороший параметр, который позволяет пользователю изменять коэффициент выборки.

Например, в SMOTE, чтобы изменить соотношение, вы должны ввести словарь, и все значения должны быть больше или равны наибольшему классу (поскольку SMOTE - это метод избыточной выборки). По моему мнению, причина, по которой SMOTE лучше подходит для производительности модели, заключается в том, что с RandomOverSampler вы дублируете строки, что означает, что модель может начать запоминать данные, а не обобщать их для новых данных. SMOTE использует алгоритм K-Nearest-Neighbours для создания "точек" данных, аналогичных точкам данных, выбранным ниже.

Иногда не рекомендуется слепо использовать SMOTE, устанавливая отношение к нему по умолчанию (даже баланс классов), потому что модель может соответствовать одному или нескольким классам меньшинства, даже если SMOTE использует ближайших соседей для "похожих" наблюдений. Подобным образом вы настраиваете гиперпараметры модели ML, вы настраиваете гиперпараметры алгоритма SMOTE, такие как отношение и/или knn. Ниже приведен рабочий пример того, как правильно использовать SMOTE.

ПРИМЕЧАНИЕ. Крайне важно, чтобы вы не использовали SMOTE для полного набора данных. Вы ДОЛЖНЫ использовать SMOTE только на обучающем наборе (т.е. после разделения), а затем проверить на проверочном наборе и тестовых наборах, чтобы увидеть, выполнила ли ваша модель SMOTE другие ваши модели. Если вы этого не сделаете, произойдет утечка данных, и вы получите совершенно не относящуюся к делу модель.

from collections import Counter
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
import numpy as np
from xgboost import XGBClassifier
import warnings

warnings.filterwarnings(action='ignore', category=DeprecationWarning)
sm = SMOTE(random_state=0, n_jobs=8, ratio={'class1':100, 'class2':100, 'class3':80, 'class4':60, 'class5':90})
X_resampled, y_resampled = sm.fit_sample(X_normalized, y)

print('Original dataset shape:', Counter(y))
print('Resampled dataset shape:', Counter(y_resampled))

X_train_smote, X_test_smote, y_train_smote, y_test_smote = train_test_split(X_resampled, y_resampled)
X_train_smote.shape, X_test_smote.shape, y_train_smote.shape, y_test_smote.shape, X_resampled.shape, y_resampled.shape

smote_xgbc = XGBClassifier(n_jobs=8).fit(X_train_smote, y_train_smote)

print('TRAIN')
print(accuracy_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))
print(f1_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))

print('TEST')
print(accuracy_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))
print(f1_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))