Авторы (в алфавитном порядке): Ник Беккер (NVIDIA), Данте Гама Дессавр (NVIDIA) и Кори Нолет (NVIDIA).

Введение

Imbalanced-learn — самая популярная библиотека с открытым исходным кодом для повторной выборки наборов данных с дисбалансом классов. Только за последний месяц его скачали более 3 миллионов раз, что делает его важной частью экосистемы анализа данных и машинного обучения.

RAPIDS cuML — это набор быстрых алгоритмов машинного обучения с ускорением на GPU, предназначенных для обработки данных и аналитических задач. Используя массивный параллелизм и высокоскоростную память графических процессоров NVIDIA, cuML может обеспечить значительное ускорение по сравнению с библиотеками машинного обучения на базе ЦП. Благодаря API, отражающему scikit-learn, cuML должен показаться пользователям знакомым.

В этом посте мы рассмотрим, как теперь вы можете использовать оценщики cuML с несбалансированным обучением, чтобы значительно быстрее запускать многие методы повторной выборки на больших наборах данных. Основываясь на наших результатах, cuML часто обеспечивает ускорение в 5–15 раз для таких методов, как SMOTE, ADASYN и EditedNearestNeighbours, и в 100–300 раз для таких методов, как SVMSMOTE и CondensedNearestNeighbour.

Почему графические процессоры?

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

Несмотря на то, что эти усовершенствования повысили производительность, на больших наборах данных многие методы повторной выборки остаются фундаментально узкими местами из-за основных вычислительных примитивов, лежащих в их основе. Например, следующий код занял около 45 минут в системе с двумя 20-ядерными процессорами Intel Xeon E5–2698 (80 логических ядер).

from imblearn.over_sampling import SVMSMOTE
from sklearn.datasets import make_classification

X, y = make_classification(
  n_samples=100000,
  n_features=100,
  n_redundant=0,
  n_informative=100,
  n_classes=5,
  n_clusters_per_class=1,
  weights=[0.8, 0.05, 0.05, 0.05, 0.05]
)

X_resampled, y_resampled = SVMSMOTE().fit_resample(X, y)

Если бы мы захотели включить этот шаг повторной выборки в более широкий конвейер машинного обучения с перекрестной проверкой, мы бы ждали довольно долго. Поскольку масштабирование часто бывает нелинейным, большие наборы данных создают еще большие проблемы. Чтобы использовать такие методы в масштабе, нам нужно сделать что-то другое.

Использование несбалансированного обучения с cuML

cuML позволяет использовать эти методы в масштабе. Вы можете установить cuML и несбалансированное обучение в одной среде, используя conda или pip.

# conda/mamba
mamba create -n rapids-imblearn -c rapidsai -c conda-forge -c nvidia rapids=23.02 python=3.8 cudatoolkit=11.5 imbalanced-learn
mamba activate rapids-imblearn

# pip
python3.8 -m venv rapids-imblearn
source rapids-imblearn/bin/activate
pip install --ugprade pip
pip install cuml-cu11 --extra-index-url=https://pypi.nvidia.com
pip install imbalanced-learn

Использовать cuML с несбалансированным обучением очень просто — просто передайте оценщик cuML в качестве аргумента при создании экземпляра выбранного вами ресемплера. В следующих разделах мы поделимся несколькими примерами, которые подчеркивают как простоту использования, так и сравнительный анализ влияния использования cuML на наборы данных разных размеров и форм.

Для эталонных наборов данных мы используем генераторы наборов данных scikit-learn и варьируем количество строк, количество функций и количество классов. Веса классов установлены на [0,9, 0,1] в сценарии с двумя классами и [0,8, 0,05, 0,05, 0,05, 0,05] в сценарии с пятью классами, чтобы представить вероятный дисбаланс. Тесты ЦП выполнялись в системе с двумя 20-ядерными ЦП Intel Xeon E5–2698 (80 логических ядер), а тесты ГП выполнялись в экземпляре Google Cloud a2-highgpu-1g с графическим процессором A100 40 ГБ и 12 виртуальными ЦП.

Передискретизация

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

УДАР

SMOTE — это метод передискретизации, который использует алгоритм ближайшего соседа для передискретизации и создания синтетических данных на основе ближайших соседей записей в недопредставленных классах. Это означает, что вычислительная производительность зависит от количества выборок на недопредставленный класс в наборе данных, а не от общего размера набора данных.

На наборе данных 10M x 20 с весами классов [0,9, 0,1] стандартный SMOTE занял около 150 секунд. Использование NearestNeighbors в cuML сокращает это время примерно до 18 секунд, то есть в 8 раз быстрее.

from imblearn.over_sampling import SMOTE
from sklearn.datasets import make_classification
from cuml.neighbors import NearestNeighbors

X, y = make_classification(
  n_samples=10000000,
  n_features=20,
  n_redundant=0,
  n_informative=100,
  n_classes=2,
  n_clusters_per_class=1,
  weights=[0.9, 0.1]
)

nn = NearestNeighbors(n_neighbors=6)
X_resampled, y_resampled = SMOTE(n_neighbors=nn).fit_resample(X, y)

В наборах данных с 10 млн строк результаты тестов показывают, что cuML может обеспечить ускорение в диапазоне от 2x до 8x.

СВМСМОТЕ

SVMSMOTE похож на SMOTE, но использует классификатор машины опорных векторов для выбора кандидатов, из которых можно генерировать данные синтетической выборки. Использование SVM делает его намного более затратным с вычислительной точки зрения, что объясняет 45-минутное время выполнения, которое мы видели в исходном примере выше.

Используя оценщики NearestNeighbors и SVC cuML, мы можем запустить исходный пример за 9 секунд, а не за 45 минут (ускорение в 285 раз).

from imblearn.over_sampling import SVMSMOTE
from sklearn.datasets import make_classification
from cuml.neighbors import NearestNeighbors
from cuml.svm import SVC

X, y = make_classification(
  n_samples=100000,
  n_features=100,
  n_redundant=0,
  n_informative=100,
  n_classes=5,
  n_clusters_per_class=1,
  weights=[0.8, 0.05, 0.05, 0.05, 0.05]
)

nn = NearestNeighbors(n_neighbors=6)
svm = SVC()
X_resampled, y_resampled = SVMSMOTE(
  k_neighbors=nn,
  m_neighbors=nn,
  svm_estimator=svm
).fit_resample(X, y)

Прирост производительности значителен для различных классов и функций, от 50x до 340x.

АДАСЫН

ADASYN также похож на обычный SMOTE, но он использует двухэтапный процесс поиска ближайших соседей для создания синтетических выборок (сначала используется полный набор данных для поиска ближайших соседей для недопредставленного класса, а затем выполняется второй проход только в рамках недопредставленного класса).

Использование полного набора данных и дополнительного шага делает его значительно более затратным в вычислительном отношении, чем обычный SMOTE, но все же меньше, чем SVMSMOTE.

from imblearn.over_sampling import ADASYN
from sklearn.datasets import make_classification
from cuml.neighbors import NearestNeighbors

X, y = make_classification(
  n_samples=10000000,
  n_features=20,
  n_redundant=0,
  n_informative=100,
  n_classes=2,
  n_clusters_per_class=1,
  weights=[0.9, 0.1]
)

nn = NearestNeighbors(n_neighbors=6)
X_resampled, y_resampled = SMOTE(n_neighbors=nn).fit_resample(X, y)

На наборах данных 10M x 20 результаты тестов показывают, что cuML может обеспечить ускорение до 13 раз.

Неполная выборка

cuML также может ускорить методы недостаточной выборки. Ниже мы выделяем два канонических метода.

Сжатый Ближайший Сосед

CondensedNearestNeighbour — это итеративный метод недостаточной выборки, который классифицирует ближайшего соседа для каждой записи в перепредставленном классе, чтобы помочь решить, сохранять ли запись. В результате очень медленно. Мы используем гораздо меньшие наборы данных для этого теста.

Как обычно, cuML можно сразу добавить (с одним дополнительным шагом для этого ресемплера):

from imblearn.under_sampling import CondensedNearestNeighbour
from sklearn.datasets import make_classification
from cuml.neighbors import KNeighborsClassifier

X, y = make_classification(
  n_samples=50000,
  n_features=20,
  n_redundant=0,
  n_informative=100,
  n_classes=2,
  n_clusters_per_class=1,
  weights=[0.9, 0.1]
)

knn = KNeighborsClassifier(n_neighbors=1)
cnn = CondensedNearestNeighbour(n_neighbors=knn)
cnn.estimator_ = knn # extra step for this resampler
X_res, y_res = cnn.fit_resample(X, y)

Только для 50 000 строк результаты тестов показывают, что cuML может обеспечить ускорение в 50–100 раз, превращая примерно час ожидания в считанные секунды в некоторых случаях.

ОтредактированоNearestNeighbours

EditedNearestNeighbours — это метод недостаточной выборки, который идентифицирует ближайших соседей каждой записи в перепредставленном классе и удаляет выборки, которые «достаточно не согласуются со своим соседством».

from imblearn.under_sampling import EditedNearestNeighbours
from sklearn.datasets import make_classification
from cuml.neighbors import NearestNeighbors

X, y = make_classification(
  n_samples=50000,
  n_features=20,
  n_redundant=0,
  n_informative=100,
  n_classes=2,
  n_clusters_per_class=1,
  weights=[0.9, 0.1]
)

nn = NearestNeighbors(n_neighbors=4)
enn = EditedNearestNeighbours(n_neighbors=nn)
X_res, y_res = enn.fit_resample(X, y)

В зависимости от характеристик набора данных ускорение cuML варьируется от 3 до 13 раз.

Заключение

Imbalanced-learn — это канонический инструмент для повторной выборки несбалансированных наборов данных в Python. Благодаря поддержке использования оценщиков RAPIDS cuML теперь можно использовать несбалансированное обучение для больших наборов данных, чем когда-либо прежде. В приведенных выше тестах мы увидели ускорение более чем в 100 раз при использовании cuML на графическом процессоре NVIDIA.

Чтобы узнать больше, посетите документацию imbalanced-learn и RAPIDS cuML.

Команда RAPIDS постоянно сотрудничает с сообществом разработчиков ПО с открытым исходным кодом, чтобы понять и удовлетворить возникающие потребности. Если вы мейнтейнер с открытым исходным кодом, заинтересованный в использовании GPU-ускорения в своем проекте, свяжитесь с Github или Twitter. Команда RAPIDS хотела бы узнать, как потенциальные новые алгоритмы или наборы инструментов повлияют на вашу работу.

Благодарности

Во время стажировки в NVIDIA Джеймс Томсон (Стэнфорд) внес свой вклад в RAPIDS cuML и scikit-learn-contrib/imbalanced-learn, чтобы сделать эту интеграцию возможной.