Поиск по сайту Поиск

Истина где‑то рядом — ищем аномалии с Python. Часть 2: практика

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

Начнём с того, что визуально оценим набор данных и посмотрим, сможем ли мы найти аномалии. Файл Jupyter Notebook с нижеизложенным кодом можно найти здесь.

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

— ФИО сотрудников организации (для 100 человек)

— их ежемесячная заработная плата (в долларах США) в диапазоне от 1000 до 2500.

Чтобы сгенерировать похожие на настоящие имена, мы будем использовать Python-библиотеку Faker, а для зарплаты подойдёт привычная numpy. После этого объединим созданные столбцы в Pandas DataFrame. 

Примечание: не пренебрегайте работой с фиктивными наборами данных, это действительно важный экспериментальный навык!

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

Теперь можно начать эксперименты.

Видеть значит верить: находим аномалии глазами

Подсказка: ящики с усами великолепны!

Как упоминалось в предыдущей статье, появление аномалий напрямую зависит от генерации самих данных. Рассмотрим немного базовой статистики (минимальное значение, максимальное, значение 1-го квартиля и т. д.) в виде ящика с усами (диаграммы размаха):

Образец ящика с усами

Мы получим:

https://paper-attachments.dropbox.com/s_1185AEC62427E23657579AF288686866FF5B3F65A0E36E86D1A293C6B0CCF4B4_1554276006076_download.png

Обратите внимание на маленький кружок в самом низу. Он сразу даёт понять, что что-то не так, потому что сильно отличается от остальных данных. 

Как насчёт гистограмм?

Результат:

https://paper-attachments.dropbox.com/s_1185AEC62427E23657579AF288686866FF5B3F65A0E36E86D1A293C6B0CCF4B4_1554276086683_download+1.png

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

Какой же способ сразу подтвердит наличие аномалий в наборе данных? Давайте посмотрим на минимальное и максимальное значение столбца «Заработная плата» (Salary):

Получим:

Минимальное значение явно отклоняется от того, что было задано раньше (1000 долларов). Следовательно, это действительно аномалия. 

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

Кластерный подход для обнаружения аномалий

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

Очень короткая заметка о евклидовом расстоянии

Если в двумерном пространстве есть n точек (см. следующий рисунок) и их координаты обозначены (x_i, y_i), то евклидово расстояние между любыми двумя точками x1, y1 и x2, y2 равно:

https://paper-attachments.dropbox.com/s_1185AEC62427E23657579AF288686866FF5B3F65A0E36E86D1A293C6B0CCF4B4_1554546141896_image.png

Уравнение евклидова расстояния
https://paper-attachments.dropbox.com/s_1185AEC62427E23657579AF288686866FF5B3F65A0E36E86D1A293C6B0CCF4B4_1554298964709_Capture+1.PNG

График с точками на двумерной плоскости

Для кластеризации мы будем использовать метод k-средних. Начнём:

Теперь импортируем модуль kmeans из scipy.cluster.vq. SciPy (Scientific Python) — это библиотека для различных научных расчётов.  Применим kmeans к salary_raw:

Во фрагменте выше мы указали в kmeans данные о зарплате и количество кластеров, по которым хотим сгруппировать точки. centroids — это центроиды, сгенерированные kmeans, а avg_distance — усреднённое евклидово расстояние между ними и точками. Давайте извлечём наши кластеры с помощью метода vq(). Его аргументы это:

— точки данных

— центроид, сгенерированный алгоритмом кластеризации.

Метод возвращает группы точек (кластеры) и расстояния между точками и ближайшими кластерами.

https://paper-attachments.dropbox.com/s_1185AEC62427E23657579AF288686866FF5B3F65A0E36E86D1A293C6B0CCF4B4_1554276804886_download+2.png

Теперь вы точно видите аномалии. Итак, несколько моментов, которые необходимо учитывать перед обучением модели:

  1. Тщательно изучите данные — взгляните на каждый признак в наборе, соберите статистику.
  2. Постройте несколько полезных графиков (как показано выше), так вам будет легче заметить отклонения.
  3. Посмотрите, как признаки связаны друг с другом. Это поможет выбрать наиболее значимые из них и отказаться от тех, что не влияют на целевую переменную (не коррелируют с ней). 

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

А почему бы и нет?

Обнаружение аномалий как проблема классификации

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

Снова взглянем на датасет:

https://blog.floydhub.com/content/images/2019/04/image-1.png

Теперь мы решаем задачу бинарной классификации. Будем искать выбросы, основываясь на подходе близости (proximity-based anomaly detection). Основная идея в том, что близость аномальной точки к её соседним точкам сильно отличается от близости других точек к их соседям. Если вам ничего не понятно, не пугайтесь — на наглядном примере всё станет ясно.

Для этого мы применим метод k-ближайших соседей и Python-библиотеку PyOD, специально предназначенную для детектирования выбросов.

Столбец “Person” для модели совершенно бесполезен, поскольку служит лишь идентификатором. Подготовим обучающую выборку:

Аргументы, переданные в KNN():

contamination: количество аномалий в данных (в процентах), в нашем случае 2/100

n_neighbors: число соседей, упитывающихся при измерении близости 

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

Попробуем оценить KNN() относительно обучающей выборки с помощью функции evaluate_print():

Получим:

Видим, что KNN() достаточно хорошо работает на обучающих данных. Он выдаёт три метрики и их оценки:

ROC

— точность

—  доверительную оценку.

Примечание: при обнаружении аномалий всегда следует учитывать эти оценки, поскольку они дают наиболее полное представление об эффективности модели.

У нас нет тестовой выборки, но мы можем сгенерировать примерное значение зарплаты:

Давайте проверим, может ли модель пометить это значение как выброс:

Вывод должен быть: array([1])

Видим, что модель не ошиблась. Проверим, как она работает с нормальными данными:

Вывод: array([0])

Модель отметила значение как обычную точку данных. 

На этом мы завершаем исследование аномалий и переходим к заключению.

Проблемы и дальнейшие исследования

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

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

Понимание разницы между шумом и аномалиями: если принять выбросы за шум или наоборот, то можно изменить весь ход процесса обнаружения аномалий, поэтому следует уделять внимание этому вопросу.

Теперь поговорим о том, как вам продвинуться в исследованиях и улучшить качество данных. Вот несколько тем, которые мы не затронули в статье:

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

Методы поиска аномалий, основанные на глубоком обучении: нейросети тоже могут помогать в поиске выбросов, и эта тема уже давно и активно исследуется.

Другие сложные методы: здесь мы рассматривали только поиск точечных аномалий. Но есть ряд алгоритмов для обнаружения контекстуальных и коллективных аномалий. Более подробную информацию о них можно найти в книге “Data Mining. - Concepts and Techniques (3rd Edition)”.

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

С оригинальной статьёй можно ознакомиться в блоге floydhub.com.

10 лучших IDE и редакторов кода для веб-разработчиков

10 лучших IDE и редакторов кода для веб-разработчиков

Писать код при желании можно и в текстовом редакторе — ничто не мешает вам создать простейший сайт в «Блокноте», сохранив...
Read More
Domains weekly: .РФ на страже русского языка, рост new gTLDs и пассивный доход от PORNO.COM

Domains weekly: .РФ на страже русского языка, рост new gTLDs и пассивный доход от PORNO.COM

В новой подборке новостей мы расскажем, как развивался русский язык вместе с зоной .РФ, что за риски таит в себе...
Read More
VPS нового поколения, ИИ, юникодные домены и мини‑сериал об админах: всё, что вы знали и чего могли не знать о REG.RU

VPS нового поколения, ИИ, юникодные домены и мини‑сериал об админах: всё, что вы знали и чего могли не знать о REG.RU

Ура-ура! 22 мая нам исполнилось 14 лет, и мы по-прежнему двигаемся только вперёд и становимся лучше. Мы решили поделиться с...
Read More
Domains weekly: старт .MEET от Google, годовой рост .RU и .РФ, вирусная реклама рэп‑альбома с new gTLDs

Domains weekly: старт .MEET от Google, годовой рост .RU и .РФ, вирусная реклама рэп‑альбома с new gTLDs

В новой еженедельной подборке новостей расскажем о старте регистраций в зоне  .MEET от Google, вирусной рекламной кампании нового рэп-альбома Future...
Read More
Как скорость загрузки страниц на мобильных устройствах влияет на посещаемость сайта

Как скорость загрузки страниц на мобильных устройствах влияет на посещаемость сайта

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

Популярные уязвимости сайтов: чем опасны и как их избежать

Для любого, кто управляет веб-сайтом, на первом месте должен стоять вопрос безопасности. Критические угрозы и уязвимости могут сильно ударить как...
Read More
Domains weekly: 10 лет .РФ, новый топ регистраторов в .COM и спор за ягодный домен

Domains weekly: 10 лет .РФ, новый топ регистраторов в .COM и спор за ягодный домен

В свежей подборке новостей расскажем о юбилее .РФ, отчёте ICANN о динамике регистраций в зоне .COM и неудачной попытке канадской...
Read More
С днём рождения, .РФ!

С днём рождения, .РФ!

В этом году кириллической национальной российской доменной зоне исполняется 10 лет. Мы решили вспомнить, как всё начиналось: в этом материале...
Read More
Domains weekly: стагнация ccTLD, конец страстей по .ORG и взлом клиентов GoDaddy

Domains weekly: стагнация ccTLD, конец страстей по .ORG и взлом клиентов GoDaddy

В сегодняшней подборке новостей расскажем, как изменилось число регистраций национальных доменов по сравнению с прошлым годом, чем закончилась сделка с...
Read More
Как поменять домен, чтобы сайт не просел в поисковой выдаче

Как поменять домен, чтобы сайт не просел в поисковой выдаче

Итак, вы решили изменить имя своего сайта после ребрендинга или просто выбрали более короткий домен. Но как при этом сохранить...
Read More