Этот пост содержит краткий обзор ключевых деталей для начала работы с изолированными лесами в scikit-learn и может послужить платформой для ваших будущих исследований.
Введение в алгоритм изолированного леса
Обнаружение аномалий — это процесс обнаружения необычных или аномальных точек данных в наборе данных. Это важный метод мониторинга и предотвращения мошенничества, а также обнаружения ошибок в данных. К сожалению, аномалии бывает очень трудно обнаружить, учитывая, что: 1) они обычно возникают нечасто, 2) они могут не иметь четких закономерностей идентификации и 3) аномалии могут быть явно разными даже в пределах одного и того же набора данных.
Изолирующий лес — один из самых популярных алгоритмов обнаружения аномалий. Общая идея изолированного леса заключается в том, что аномалии данных (выбросы) легче отделить (изолировать) от более широкого набора данных, учитывая, что они обладают уникальными характеристиками, вероятность возникновения которых меньше. По сути, алгоритм переворачивает проблему с ног на голову, изучая характеристики нормальных данных, чтобы различать аномальные точки данных. Учитывая, что в данных нет меток (аномалии, как правило, трудно пометить), это неконтролируемый алгоритм.
Алгоритм работает путем построения нескольких деревьев решений для классификации точек данных. Каждое дерево решений будет построено с использованием различных подмножеств входных функций, которые затем объединяются для формирования окончательного дерева решений. Изолирующий лес работает, разделяя пространство данных на n сегментов как разбиения, которые ортогональны исходной точке (попробуйте визуализировать разделительные линии, проведенные через набор данных) и присвоит более высокие оценки аномалии точкам данных, которым требуется только несколько из них. расколы должны быть изолированы. Для получения более подробной информации об изолированном лесу вы можете просмотреть документацию scikit-learn здесь.
Зачем использовать изолированный лес для обнаружения аномалий?
Краткий обзор преимуществ использования изолированного леса для обнаружения аномалий заключается в следующем:
- Это популярный алгоритм с надежной документацией сообщества.
- Он имеет линейную временную сложность с, возможно, низкими требованиями к вычислительным ресурсам.
- Он не использует никаких мер расстояния или плотности, что помогает поддерживать алгоритм сравнительно быстрым.
- Кажется, он хорошо работает с задачами большой размерности, которые могут иметь большое количество нерелевантных атрибутов.
Возможные ограничения при использовании изолированного леса
- Отмечена проблема, заключающаяся в том, что алгоритм не может идентифицировать локальные аномальные точки, что может повлиять на точность. Подробнее по этому вопросу можно узнать здесь.
- Учитывая, что это неконтролируемый алгоритм, будет трудно понять, действительно ли вы правильно идентифицируете аномалии, что потребует поддержки ключевых заинтересованных сторон в проблемной области.
Требования к алгоритму и входные параметры
Ключевыми требованиями для этого проекта являются установленные на вашем компьютере numpy, pandas и scikitlearn. Кроме того, для визуального изучения данных мы будем использовать matplotlib, seaborn и plotly express.
Для начала давайте проверим параметры алгоритма изолированного леса, используя функцию справки Python.
from sklearn.ensemble import IsolationForest help(IsolationForest)
Важными параметрами в алгоритмах являются:
- количество деревьев / оценщики: насколько велик лес
- загрязнение: часть набора данных, которая содержит аномальные экземпляры, т.е. 0,1 или 10%. Алгоритм очень чувствителен к этому параметру, и невероятно полезно иметь первоначальное представление об ожидаемой частоте возникновения аномалий.
- макс. выборки: количество выборок из обучающего набора для обучения каждого дерева изоляции.
- максимальная глубина: насколько глубоким должно быть дерево, это можно использовать для обрезки дерева и ускорения работы.
Пример кода обнаружения мошенничества с кредитными картами
В этом примере мы проанализируем набор данных транзакций по кредитным картам на наличие аномалий, используя алгоритм изолированного леса. Набор данных содержит транзакции, совершенные по кредитным картам в сентябре 2013 года держателями карт из Европы. Этот набор данных представляет транзакции, которые произошли за два дня, где у нас есть 492 мошенничества из 284 807 транзакций. Набор данных сильно несбалансирован, положительный класс (мошенничество = 1) составляет 0,172% всех транзакций и доступен здесь благодаря kaggle.
Импорт основных модулей
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns pd.set_option("display.float", "{:.2f}".format) %matplotlib inline sns.set_style("whitegrid")
загружать данные и проверять столбцы
data = pd.read_csv("creditcard.csv") data.head()
data['Class'].value_counts()
Набор данных имеет 31 столбец, состоящий из 30 потенциальных признаков и 1 столбца меток «Класс» (аномалии = 1). Мы также подтверждаем, что класс содержит очень мало аномалий (492).
Исследование функции времени
Набор данных содержит столбец времени (в секундах), который потенциально может повлиять на то, как мы подходим к проблеме. В распределении времени между мошенническими и немошенническими транзакциями нет визуальной зависимости.
plt.figure(figsize=(14, 12)) plt.subplot(2, 2, 1) data[data.Class == 1].Time.hist(bins=35, color='blue', alpha=0.6, label="Fraudulant Transaction") plt.legend() plt.subplot(2, 2, 2) data[data.Class == 0].Time.hist(bins=35, color='blue', alpha=0.6, label="Non Fraudulant Transaction") plt.legend()
Используйте PCA, чтобы попытаться визуализировать аномалии
Используя PCA, мы можем визуализировать проблемы высокой размерности в плоскости более низкого измерения. Из матрицы разброса видно, что аномалии имеют тенденцию занимать определенные области в разбросах, особенно для компонентов PC1 и PC3. Что мы хотели бы увидеть в конце этого упражнения, так это то, что изолированный лес идентифицирует похожие регионы после обучения.
import plotly.express as px from sklearn.decomposition import PCA n_components=3 pca = PCA(n_components=n_components) components = pca.fit_transform(data) total_var = pca.explained_variance_ratio_.sum() * 100 labels = {str(i): f"PC {i+1}" for i in range(n_components)} labels['color'] = 'Class' fig = px.scatter_matrix( components, color=data['Class'], dimensions=range(n_components), labels=labels, title=f'Total Explained Variance: {total_var:.2f}%', ) fig.update_traces(diagonal_visible=False) fig.show()
Подготовка данных
Дополнительные преобразования, такие как логарифмическая нормализация и минимальное-максимальное масштабирование, не требуются для изолированных лесов, поскольку они должны иметь минимальное влияние на количество «алгоритмических срезов», необходимых для изоляции точек данных.
Разделение изолированного леса на обучающие, тестовые и проверочные наборы обычно не требуется, учитывая, что в большинстве случаев помеченные данные об аномалиях будут недоступны, чтобы судить о точности. В этом примере мы просто сравним прогнозы с фактической меткой для всего набора данных.
X = data.drop('Class', axis=1) y = data.Class from sklearn.ensemble import IsolationForest Iforest = IsolationForest(max_samples=100, random_state=1111, contamination=0.05, max_features=1.0, n_estimators=100, verbose=1, n_jobs=-1) Iforest.fit(X)
Алгоритм идентифицировал 14241 точку данных как аномальную (около 5%), что точно соответствует первоначально заданному входному параметру загрязнения.
y_pred = Iforest.predict(X) y_pred_adjusted = [1 if x == -1 else 0 for x in y_pred] sum(y_pred_adjusted) Out: 14241
Оценка
Учитывая, что мы сосредоточены на обнаружении аномалий, важно измерять эффективность алгоритма на основе точности или отзыва, а не точности.
Для оценки алгоритма мы будем вычислять метрики глобально, подсчитывая общее количество истинных срабатываний, ложноотрицательных и ложноположительных результатов. Sklearn имеет встроенные функции для поддержки вычисления показателей точности, отзыва, F-меры и поддержки каждого класса.
- Точность — это отношение tp / (tp + fp), где tp — количество истинных срабатываний, а fp — количество ложных срабатываний. Точность — это интуитивно способность классификатора не маркировать отрицательный образец как положительный.
- Отзыв представляет собой отношение tp / (tp + fn), где tp — количество истинных положительных результатов, а fn — количество ложноотрицательных результатов. Под отзывом понимается интуитивно способность классификатора находить все положительные образцы.
- Показатель F1 можно интерпретировать как среднее гармоническое между точностью и полнотой, где показатель F1 достигает своего наилучшего значения при 1, а наихудший показатель при 0. F1 = 2 * (точность * полнота) / (точность + полнота)
Однако точность 88% с точки зрения обнаружения аномалий является очень обнадеживающим результатом и означает, что алгоритм точно выделяет аномальные данные.
from sklearn.metrics import precision_recall_fscore_support precision_recall_fscore_support(y, y_pred_adjusted, average='macro') Out: (0.5140217751041775, 0.8862351802914121, 0.5148736994136962, None)
Как видно из матрицы путаницы, модель ложно предсказывает, что большая часть значений является аномалией, несмотря на то, что согласно меткам это не так.
from sklearn.metrics import confusion_matrix cm = confusion_matrix(y, y_pred_adjusted) from sklearn.metrics import ConfusionMatrixDisplay disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[0, 1]) disp.plot() plt.show()
Интересно, что алгоритм идентифицировал очень специфические области как аномалии. Хотя это может показаться чрезмерно агрессивным распределением аномалий, оно кажется разумным.
data['predictions'] = Iforest.predict(X) data['predictions'] = np.where(data['predictions']==-1,1,0) n_components=3 pca = PCA(n_components=n_components) components = pca.fit_transform(data) total_var = pca.explained_variance_ratio_.sum() * 100 labels = {str(i): f"PC {i+1}" for i in range(n_components)} labels['color'] = 'Class' fig = px.scatter_matrix( components, color=data['predictions'], dimensions=range(n_components), labels=labels, title=f'Total Explained Variance: {total_var:.2f}%', ) fig.update_traces(diagonal_visible=False) fig.show()
Похоже, что алгоритм фокусируется на областях с низкой плотностью и высокой дисперсией, чего мы и ожидали.
Чувствительность лесов изоляции к параметру загрязнения
Я подтвердил чувствительность алгоритма к фактору загрязнения после проведения нескольких последовательных запусков моделирования. Фактор загрязнения 2% (что близко к ожидаемому) обеспечивает приемлемую точность, гарантируя, что ложные срабатывания сведены к минимуму.
Так, что дальше?
Хорошее представление об ожидаемых частотах аномалий действительно важно для достижения хорошего баланса между точностью модели и минимизацией частоты ложных срабатываний.
Следующие шаги, вероятно, будут включать развертывание модели в производственной среде. Алгоритм начнет обнаруживать аномалии, а допущения модели можно будет уточнять посредством непрерывного тестирования.
Комбинация изолированного леса с ансамблем неконтролируемых алгоритмов обнаружения аномалий может быть лучшим способом, однако с моей стороны требуются дальнейшие исследования. Надеюсь, это поможет и удачи в ваших исследованиях.
Вы можете получить доступ к примеру кода здесь.
Использованная литература:
- https://towardsdatascience.com/isolation-forest-and-spark-b88ade6c63ff
- https://scikit-learn.org/stable/auto_examples/ensemble/plot_isolation_forest.html#sphx-glr-auto-examples-ensemble-plot-isolation-forest-py
- https://scikit-learn.org/stable/modules/generated/sklearn.metrics.ConfusionMatrixDisplay.html
- https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html
- https://stackoverflow.com/questions/60877853/data-normalization-needed-for-isolation-forest