Руководство по методам обнаружения выбросов с примерами на Python

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

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

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

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

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

Метод квантилей в Pandas позволяет легко рассчитать IQR. Для методов кластеризации в библиотеке Scikit-learn на Python есть простая в использовании реализация алгоритма DBSCAN, которую можно легко импортировать из модуля кластеров в Scikit-learn. Эта простота использования особенно идеальна для новичков, поскольку пакеты Scikit-learn позволяют пользователям работать с алгоритмом по умолчанию, который требует минимальных требований от специалиста по данным. Кроме того, интерфейс каждого из этих алгоритмов позволяет пользователям легко изменять параметры для быстрого прототипирования и тестирования.

Мы будем работать с Набором данных о мошенничестве с кредитными картами. Мы применим IQR и DBSCAN для обнаружения выбросов в этих данных и сравнения результатов. Эти данные имеют Открытую лицензию базы данных и могут свободно распространяться, изменяться и использоваться.

Чтение данных

Давайте начнем с импорта библиотеки Pandas и чтения наших данных во фрейм данных Pandas:

df = pd.read_csv("creditcard.csv")

Затем давайте ослабим ограничения отображения для столбцов и строк, используя метод Pandas set_option():

pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

В демонстрационных целях мы будем работать с уменьшенной версией данных:

df = df.sample(30000, random_state=42)
df.to_csv("creditcard_downsampled5000.csv", index=False)

Теперь давайте отобразим первые пять строк данных с помощью метода head():

print(df.head())

Как мы видим, в наборе данных есть столбцы с V1 по V28, которые отражают 28 основных компонентов, сгенерированных с использованием признаков, соответствующих информации о транзакциях. Информация об оригинальных функциях не является общедоступной из-за конфиденциальности клиентов.

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

Межквартильные диапазоны (IQR)

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

  • Первый квартиль (Q1) соответствует значению, при котором 25 процентов данных находятся ниже этой точки.
  • Второй квартиль (Q2) — это среднее значение столбца данных. 50 процентов данных в этом столбце находятся ниже этого значения.
  • Третий квартиль (Q3) — это точка, в которой 75 процентов данных в столбце находятся ниже этого значения.
  • IQR — это разница между третьим квартилем (Q3) и первым квартилем (Q1).

После вычисления первого и третьего квартилей вычислить IQR несложно. Мы просто берем разницу между третьим и первым квартилями (Q3 минус Q1). Получив IQR, мы можем использовать его для обнаружения выбросов в наших столбцах данных.

Использование IQR для обнаружения выбросов называется правилом 1,5 x IQR. Используя это правило, мы вычисляем верхнюю и нижнюю границы, которые мы можем использовать для обнаружения выбросов. Верхняя граница определяется как третий квартиль плюс 1,5-кратный IQR. Нижняя граница определяется как первый квартиль минус 1,5-кратный IQR.

Он работает следующим образом:

  1. Рассчитать верхнюю границу: Q3 + 1,5 x IQR
  2. Рассчитать нижнюю границу: Q1–1,5 x IQR
  3. Вычислите выбросы, удалив любое значение меньше нижней границы или больше верхней границы.

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

sns.set()
sns.boxplot(y = df['V14'])
plt.show()

Здесь мы видим, что мы получаем большое количество информации, сжатой в один сюжет. Скорее всего, первое, что мы заметим, — это синий прямоугольник, соответствующий IQR. Внутри синего прямоугольника медиане соответствует вертикальная черная линия. Левый и правый края синего прямоугольника соответствуют Q3 и Q1 соответственно. Крайняя левая и крайняя правая вертикальные черные линии соответствуют верхней и нижней границам соответственно. Наконец, черные точки слева и справа соответствуют выбросам. Мы можем использовать значения верхней и нижней границ, чтобы удалить выбросы, а затем подтвердить, что они были удалены, создав еще одну коробчатую диаграмму.

Сначала давайте рассчитаем IQR для этого столбца, что означает, что нам сначала нужно рассчитать Q1 и Q3. К счастью, в Pandas есть простой метод, называемый квантилем, который позволяет нам это сделать. Для расчета Q1 мы вызываем метод quantile() с входным параметром 0,25 (для 25-го процентиля):

Q1=df['V13'].quantile(0.25)
print("Q1:", Q1)

Мы видим, что первый квартиль (Q1) равен -0,64. Это означает, что только 25 процентов данных в столбце V13 ниже -0,64.

Чтобы рассчитать Q3, мы вызываем метод quantile() с входным параметром 0,75 (для 75-го процентиля):

Q3=df['V13'].quantile(0.75)
print("Q3:", Q3)

Мы видим, что третий квартиль (Q3) равен 0,66. Это означает, что 75 процентов данных в столбце V13 ниже 0,66.

И IQR — это просто разница между Q3 и Q1:

IQR=Q3-Q1

Отсюда мы можем определить новую серию Pandas, содержащую значения V13 без выбросов:

IQR=Q3-Q1
print("IQR: ", IQR)

Мы видим, что IQR равен 1,3. Это расстояние между Q3 и Q1.

Отсюда мы можем вычислить верхнюю и нижнюю границы. Нижняя граница Q1–1,5 x IQR:

lower_bound = Q1 - 1.5*IQR
print("Lower Bound:", lower_bound)

Мы видим, что нижняя граница равна -2,61. Следовательно, любое значение ниже -2,61 является выбросом.

Верхняя граница Q3 + 1,5 x IQR:

upper_bound = Q3 + 1.5*IQR
print("Upper Bound:", upper_bound)

Мы видим, что верхняя граница равна 2,62. В результате любое значение выше 2,62 является выбросом.

Итак, наш метод удаления выбросов для этого столбца состоит в том, чтобы удалить любое значение выше 2,62 и ниже -2,61:

df_clean = df[(df['V13']>lower_bound)&(df['V13']<upper_bound)]

Теперь мы можем построить очищенные данные:

sns.boxplot(y = df_clean['V13'])
plt.show()

Мы видим, что точки за пределами верхней и нижней границ были удалены

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

Чтобы понять это, рассмотрим средний доход в США: на момент написания статьи он составлял 44 225 долларов. Хотя это значение попадает в IQR всех доходов в США, оно может квалифицироваться как выброс, если мы рассмотрим другие факторы. Например, 44 225 долларов США, вероятно, будут исключительным доходом для врачей в США, которые практикуют в течение 10 лет. Чтобы зафиксировать различные формы в наших данных, которые могут описывать подобные ситуации, лучшим подходом является кластеризация.

DBSCAN

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

Давайте используем DBSCAN для выявления выбросов в данных, с которыми мы работали. Для начала давайте визуализируем несколько кластеров, чтобы понять, как работает алгоритм. Давайте создадим график рассеяния V13 по сравнению с V14:

sns.scatterplot(df['V13'], df['V14'])

Мы видим, что у нас есть довольно плотно упакованный кластер со многими точками-выбросами, далекими от кластера. Интересно, что некоторые точки-выбросы в этом двумерном пространстве попали бы в IQR V13 и ошибочно остались бы в данных. Посмотрите на точки на графике, близкие к нулю для V13 и -20 для V14. Значения V13 в порядке, тогда как значения V14 являются выбросами. Это делает эти точки выбросами.

Хотя мы могли бы удалить выбросы как из V13, так и из V14, чтобы исправить это, делать это для каждого столбца становится трудоемко, особенно если вы работаете с десятками функций.

Давайте посмотрим, как мы можем использовать кластеризацию, чтобы добиться большего успеха, чем метод IQR. Давайте импортируем алгоритм DBSCAN из Scikit-learn:

from sklearn.cluster import DBSCAN

Далее, давайте определим наши обучающие данные. Рассмотрим столбцы V13 и V14:

X_train = df[['V13', 'V14']]

Теперь давайте применим наш метод кластеризации к обучающим данным. Для простоты давайте сохраним значения по умолчанию, оставив входные параметры пустыми:

model = DBSCAN()
model.fit(X_train)

Давайте создадим точечную диаграмму, где мы пометим выбросы:

cluster_labels = model.labels_
plt.scatter(df["V13"], df["V14"], c = cluster_labels)
plt.show()

Мы видим, что алгоритм отлично справляется с маркировкой выбросов, и даже тех, которые метод IQR пропустил бы. Черные точки на диаграмме рассеяния соответствуют 2D-выбросам V13/V14, а красные точки — хорошим точкам данных.

Теперь мы можем легко удалить эти выбросы на основе этих меток кластера. Давайте сохраним метки кластера в новом столбце нашего фрейма данных:

df['labels'] = cluster_labels

Далее давайте удалим выбросы. Реализация Scikit-learn DBSCAN присваивает значение метки кластера, равное -1, зашумленным образцам (выбросам). Мы можем легко удалить эти значения и сохранить очищенные данные в новой переменной:

df_cluster_clean = df[df['labels'] != -1]

Теперь давайте построим наши очищенные данные:

Мы видим, что у нас больше нет точек выбросов в наших исходных данных. Что наиболее важно, выбросы, которые пропустил метод IQR, когда мы смотрели только на V13, также были удалены.

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

Код в этом посте доступен на GitHub.

Выводы

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

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

Если вам интересно узнать об основах программирования на Python, манипулировании данными с помощью Pandas и машинном обучении в Python, ознакомьтесь с Python для науки о данных и машинного обучения: Python Programming, Pandas и Scikit-learn Tutorials for Beginners. Надеюсь, вы нашли этот пост полезным/интересным.

Это сообщение изначально было опубликовано во Встроенном блоге. Оригинал произведения можно найти здесь.