CADE — интересный способ поиска аномалий в многомерных данных
Last updated
Last updated
Один из способов искать аномалии в наборе данных — использовать соответствующую данным плотность случайной величины как оценку «аномальности» точек. Интуиция проста — чем меньше значение плотности распределения в точке, тем более эта точка «аномальна». И наоборот, области с высокими значениями плотности распределения соответствуют наборам более «нормальных» точек. То есть зная плотность распределения, мы, в одной из возможных постановок задачи, можем находить и аномалии. И именно в обладании (а реальной жизни в приближении) плотности вероятности и возникает трудность, особенно когда мы работаем с данными большой размерности, и стандартные способы приближения плотности становятся вычислительно дорогими. На помощь приходят более «хитрые» способы приблизить плотность вероятности. Существует целый класс таких методов, и один из них произвёл на меня особое впечатление оригинальностью своей мысли. Он показался мне достаточно интересным для того, чтобы более популярно изложить его на Хабре. Этот метод называется CADE (Classifier Adjusted Density Estimation), и впервые он был изложен еще в 2001 году в статье [1], хотя его реальный потенциал был исследован позже.
CADE — это метод приближения плотности распределения, который хорошо справляется с большими размерностями и неинформативными признаками. Что важно, для корректной работы он требует предположения о независимости признаков. Однако по утверждениям этой статьи [2], метод ранжирует точки по аномальности на том же уровне, а при некоторых условиях даже лучше, чем LOC (Local Outlier Factor) — один из популярных density‑based методов для поиска аномалий. Суть работы CADE заключается в использовании любого любимого вами алгоритма классификации, обученного различать известные данные от искусственно сгенерированных точек. И как это нам поможет приблизить плотность распределения? Итак, давайте рассмотрим.
Если вкратце, то CADE предлагает следующее:
Смешать исходные данные с данными из произвольного (но известного заранее) распределения;
Построить классификатор, способный различать данные из двух распределений, то есть решить задачу двухклассовой классификации;
Использовать предсказания классификатора в аналитически выведенной формуле, чтобы восстановить плотность распределения изначальных данных.
Как это работает? Давайте разбираться.
Я буду использовать нотации из вышеупомянутой статьи [2], на которую я и опирался, чтобы вам было проще её перечитать, если у вас возникнет такое желание.
Пусть T — это имеющиеся данные (с небольшой долей аномалий). P(X|T) — их плотность распределения, которую мы хотим приблизить. Первое, что нам надо сделать — это выбрать то самое «произвольное» распределение, из которого мы можем сгенерировать данные. Обозначим его как A, а соответствующую плотность распределения — P(X|A). Авторы статьи утверждают, что в качестве такого распределения хорошо подходит равномерное или нормальное распределения, хотя ограничений на выбор распределения нет. Желательно только, чтобы оно полностью покрывало данные, то есть была ненулевая вероятность выбрать точку, близкую к изначальным данным. Что касается размера выборки, то авторы использовали размер, равный размеру выборки T, однако я поделюсь своими соображениями на этот счёт позже. Точки из A иногда называют искусственными аномалиями.
Следующий шаг — выбрать классификатор. В качестве него мы можем использовать всё, что способно рассчитать вероятность принадлежность точки к изначальному классу T, а именно P(C = T|X). Классификатором может быть Random Forest Classifier, KNN, Decision Tree Classifier, подходящая по архитектуре нейронная сеть и так далее.
Естественно, для каждой точки сумма вероятностей быть в классе T и классе A равна 1. Другими словами:
Теперь приступим к выводу формулы, которая позволит нам использовать предсказание классификатора для приближения изначальной плотности распределения P(X|T). Для этого мы применим теорему Байеса к P(C=T|X):
Далее, решив это уравнение относительно P(X|T), получим следующую формулу:
Это и есть приближение искомой плотности распределения по CADE! Оно состоит из трёх основных множителей.
Это отношение, которое может быть приближено как отношение количества элементов в сгенерированном и изначальном множестве данных:
Известная плотность распределения у сгенерированных данных:
Отношение, вычисляемое по предсказаниям классификатора:
Если P(X|A) — константа, то есть A было выбрано из равномерного распределения, то ранжирование точек по значениям плотности распределения будет совпадать с ранжированием по значениям классификатора (умножение на положительную константу не повлияет на порядок).
Если же мы угадали и выбрали P(X|A) близким к P(X|T), то классификатор не сможет различить распределения и для всех точек предскажет значение 0.5. Тогда ранжирование логичным образом будет совпадать с ранжированием по P(X|A).
Покончим с формулами! Давайте посмотрим на небольшую анимацию о процессе работы CADE без вычислений и финальной формулы.
Как я упомянул выше, исследователи из [2] показали, что метод действительно хорошо работает с данными высокой размерности и при наличии «шумных» атрибутов. А также использование множителя P(X|A), что является отличительной особенностью CADE, улучшает работу метода при наличии коррелирующих признаков. Если у вас будет желание, я рекомендую ознакомиться с результатами из этого исследования. В нем вы также увидите значения метрики ROC AUC для разных наборов данных и классификаторов.
На момент написания статьи, я не обнаружил реализации CADE на Python (не путать с другим CADE — Compass‑aligned Distributional Embeddings, реализация для которого есть в PyPI). Поэтому в этой статье, а также на Github (cade‑outliers), я оставлю пример кода, который реализует поиск аномалий с помощью этого метода.
Предложения по улучшению кода приветствуются!
Класс CADEOutliers
отвечает за то, чтобы приближать плотность распределения исходных данных и возвращать точки, ранжированные по значениям плотности.
Генерирование данных и применение к ним CADE:
Несколько наблюдений, которые могут оказаться полезными для вас:
Переобученный классификатор более склонен считать любые увиденные в процессе обучения точки «нормальными» (даже те, что кажутся аномалиями), а любые области без исходных данных при обучении — аномальными (даже те, что лежат рядом с увиденными точками). Другими словами, переобучение классификатора ведет к более детальному описанию плотности вероятности и большей чувствительностью к обнаружению аномалий.
Бóльшая плотность заполнения пространства искусственными аномалиями также ведет к более детальному описанию плотности распределения, т. е. к тому же эффекту, что и переобученный классификатор.
Из статьи [2] — в качестве классификатора неплохо подходит Random Forest Classifier и KNN, а в качестве распределения для искусственных аномалий — равномерное.
Я буду рад, если CADE показался интересным и вам. Особенно, если вам захочется применить его на практике и поделиться своими наблюдениями о его работе. Делитесь своим мнением в комментариях!
[1] T. Hastie, R. Tibshirani, and J. H. Friedman. The Elements of Statistical Learning: Data Mining, Inference, and Prediction. New York: Springer-Verlag, 2001.