Техники недоотбора данных с использованием Python

Техники отбора данных с использованием Python избегая недочетов

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

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

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

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

Это всего лишь несколько примеров, которые подчеркивают глубокое влияние несоответствия данных, то есть, когда один класс значительно превосходит другой. Оверсемплинг и андерсемплинг – две стандартные техники предварительной обработки данных для балансировки набора данных, которыми мы сосредоточимся в этой статье.

Давайте обсудим некоторые популярные методы для уменьшения выборки данного распределения.

Понимание недостатков дисбаланса

Давайте начнем с иллюстративного примера, чтобы лучше понять значимость техник субдискретизации. Ниже приведена визуализация влияния относительного количества точек на каждый класс, как реализовано с помощью метода опорных векторов со линейным ядром. Код и графики ниже взяты из заметки Kaggle.

import matplotlib.pyplot as pltfrom sklearn.svm import LinearSVCimport numpy as npfrom collections import Counterfrom sklearn.datasets import make_classificationdef create_dataset(    n_samples=1000, weights=(0.01, 0.01, 0.98), n_classes=3, class_sep=0.8, n_clusters=1):    return make_classification(        n_samples=n_samples,        n_features=2,        n_informative=2,        n_redundant=0,        n_repeated=0,        n_classes=n_classes,        n_clusters_per_class=n_clusters,        weights=list(weights),        class_sep=class_sep,        random_state=0,    )def plot_decision_function(X, y, clf, ax):    plot_step = 0.02    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1    xx, yy = np.meshgrid(        np.arange(x_min, x_max, plot_step), np.arange(y_min, y_max, plot_step)    )    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])    Z = Z.reshape(xx.shape)    ax.contourf(xx, yy, Z, alpha=0.4)    ax.scatter(X[:, 0], X[:, 1], alpha=0.8, c=y, edgecolor="k")fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12))ax_arr = (ax1, ax2, ax3, ax4)weights_arr = (    (0.01, 0.01, 0.98),    (0.01, 0.05, 0.94),    (0.2, 0.1, 0.7),    (0.33, 0.33, 0.33),)for ax, weights in zip(ax_arr, weights_arr):    X, y = create_dataset(n_samples=1000, weights=weights)    clf = LinearSVC().fit(X, y)    plot_decision_function(X, y, clf, ax)    ax.set_title("Линейный SVC с y={}".format(Counter(y)))

Код выше создает графики для четырех различных распределений, начиная с сильно несбалансированного набора данных, в котором один класс доминирует на 97% экземпляров. Второй и третий графики имеют соответственно 93% и 69% экземпляров от одного класса, в то время как последний график имеет абсолютно сбалансированное распределение, то есть все три класса вносят равный вклад в набор данных. Графики наборов данных от самого несбалансированного до наименее сбалансированного отображаются ниже. После обучения SVM на этих данных, гиперплоскость на первом графике (сильно несбалансированном) смещается к одному из углов, поскольку алгоритм обрабатывает каждый экземпляр одинаково, независимо от класса, и стремится разделить классы с максимальным отступом. Таким образом, большинство желтого населения рядом с центром смещает гиперплоскость в угол, что делает алгоритм неправильно классифицирующим меньшинство классов.

Алгоритм успешно классифицирует все интересующие классы по мере того, как мы приближаемся к более сбалансированному распределению.

В итоге, когда набор данных доминируется одним или несколькими классами, последующее решение часто приводит к модели с большим количеством ошибок классификации. Однако, классификатор все больше проявляет уменьшение предубежденности по мере приближения распределения наблюдений в каждом классе к равномерному делению.

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

Библиотека Imbalanced-Learn

Мы будем использовать библиотеку Imbalanced-Learn для Python (imbalanced-learn или imblearn). Мы можем установить ее с помощью pip:

pip install -U imbalanced-learn

Практическое занятие!

Давайте обсудим и попробуем некоторые из самых популярных методов уменьшения выборки. Предположим, у вас есть набор данных для бинарной классификации, где класс ‘0’ значительно превосходит класс ‘1’.

Метод NearMiss для уменьшения выборки

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

NearMiss-1: Экземпляры большинственного класса с минимальным средним расстоянием до трех ближайших экземпляров класса меньшинства.

NearMiss-2: Экземпляры большинственного класса с минимальным средним расстоянием до трех самых отдаленных экземпляров класса меньшинства.

NearMiss-3: Экземпляры большинственного класса с минимальным расстоянием до каждого экземпляра класса меньшинства.

Давайте продемонстрируем алгоритм уменьшения выборки NearMiss-1 на примере кода:

# Импортирование необходимых библиотек и модулейimport numpy as npimport matplotlib.pyplot as pltfrom collections import Counterfrom sklearn.datasets import make_classificationfrom imblearn.under_sampling import NearMiss# Генерация набора данных с различными весами классовfeatures, labels = make_classification(    n_samples=1000,    n_features=2,    n_redundant=0,    n_clusters_per_class=1,    weights=[0.95, 0.05],    flip_y=0,    random_state=0,)# Вывод распределения классовdist_classes = Counter(labels)print("После уменьшения выборки:")print(dist_classes)# Генерация графика экземпляров, помеченных по классамfor class_label, _ in dist_classes.items():    instances = np.where(labels == class_label)[0]    plt.scatter(features[instances, 0], features[instances, 1], label=str(class_label))plt.legend()plt.show()# Настройка метода уменьшения выборкиundersampler = NearMiss(version=1, n_neighbors=3)# Применение преобразования к набору данныхfeatures, labels = undersampler.fit_resample(features, labels)# Вывод нового распределения классовdist_classes = Counter(labels)print("После уменьшения выборки:")print(dist_classes)# Генерация графика экземпляров, помеченных по классамfor class_label, _ in dist_classes.items():    instances = np.where(labels == class_label)[0]    plt.scatter(features[instances, 0], features[instances, 1], label=str(class_label))plt.legend()plt.show()

Измените version=1 на version=2 или version=3 в классе NearMiss(), чтобы использовать алгоритмы NearMiss-2 или NearMiss-3 для недоработки.

 

NearMiss-2 выбирает экземпляры, находящиеся в ядре области перекрытия между двумя классами. С использованием алгоритма NearMiss-3 мы наблюдаем, что каждый экземпляр в малочисленном классе, перекрывающем область большинства, имеет до трех соседей из большинства класса. Атрибут n_neighbors в приведенном выше коде определяет это.

Правило сокращенного ближайшего соседа (CNN)

 

Этот метод начинается с того, что рассматривается подмножество класса большинства как шум. Затем он использует алгоритм 1-ближайшего соседа для классификации экземпляров. Если экземпляр из класса большинства неверно классифицирован, он включается в подмножество. Процесс продолжается, пока в подмножество не будет включено больше экземпляров.

from imblearn.under_sampling import CondensedNearestNeighbourcnn = CondensedNearestNeighbour(random_state=42)X_res, y_res = cnn.fit_resample(X, y)

Tomek Links сжатие

 

Tomek Links представляют собой близко расположенные пары экземпляров противоположных классов. Удаление экземпляров класса большинства каждой пары увеличивает расстояние между двумя классами, облегчая процесс классификации.

from imblearn.under_sampling import TomekLinkstl = TomekLinks()X_res, y_res = tl.fit_resample(X, y)print('Исходная форма набора данных:', Counter(y))print('Форма нового набора данных:', Counter(y_res))

С помощью этого мы рассмотрели основные аспекты методов недоработки в Python, включая три выдающихся метода: недоработка Near Miss, сжатый ближайший сосед и недоработка Tomek Links.

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

Эта статья предоставляет всеобъемлющее понимание методов недоработки и их применение в Python. Надеюсь, она поможет вам принимать обоснованные решения при решении проблем дисбаланса классов в ваших проектах машинного обучения.

[Видхи Чуг](https://vidhi-chugh.medium.com/) – стратег по искусственному интеллекту и лидер по цифровой трансформации, работающий на стыке продукта, наук и инженерии для создания масштабируемых систем машинного обучения. Она является лидером в области инноваций, автором и международным спикером. Она нацелена на демократизацию машинного обучения и преодоление сложного жаргона, чтобы каждый мог стать частью этой трансформации.