Ответ 1
SMOTE не является встроенным в scikit-learn, но, тем не менее, есть онлайн-реализации.
Вот, к примеру.
Я использую scikit-learn в своей программе Python для выполнения некоторых операций машинного обучения. Проблема в том, что мой набор данных имеет серьезные проблемы с дисбалансом.
Кто-нибудь знаком с решением проблемы дисбаланса в scikit-learn или в python вообще? В Java есть SMOTE-механизм. Есть что-то параллельное в python?
SMOTE не является встроенным в scikit-learn, но, тем не менее, есть онлайн-реализации.
Вот, к примеру.
Здесь есть новый
https://github.com/scikit-learn-contrib/imbalanced-learn
Он содержит множество алгоритмов в следующих категориях, включая SMOTE
В Scikit Learn есть несколько методов коррекции дисбаланса, которые варьируются в зависимости от того, какой алгоритм обучения вы используете.
Некоторые из них, такие как Svm или логистическая регрессия, имеют параметр class_weight
. Если вы создаете экземпляр SVC
с этим параметром, установленным на 'auto'
, он будет взвешивать каждый пример класса пропорционально частоте, обратной его.
К сожалению, для этой цели не существует препроцессорного инструмента.
Здесь я нашел еще одну библиотеку, которая реализует заниженную выборку, а также несколько методов избыточной SMOTE
включая несколько реализаций SMOTE
и другую, которая использует SVM
:
Пакет Python для преодоления проклятия несбалансированных наборов данных в машинном обучении
Поскольку другие перечислили ссылки на очень популярную библиотеку 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.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))