Русский
Русский
English
Статистика
Реклама

Кластеризация

Мониторинг с высокой доступностью. Опыт компании СберСервис

05.01.2021 16:09:52 | Автор: admin

СберСервис крупнейшая сервисная компания федерального значения, оказывающая услуги по комплексному техническому обслуживанию широкого спектра информационно-телекоммуникационного оборудования, рабочих мест, офисной техники, серверов и телефонии. Компания является единственным на территории СНГ премиум-партнером компании Zabbix, в ней работает самая крупная команда в России в сфере ИТ-мониторинга, разрабатывая уникальные технические решения в области комплексного внедрения систем мониторинга для организаций с высоконагруженной ИТ-инфраструктурой. Данный факт объясняет, почему в качестве основной платформы для мониторинга СберСервис выбирает Zabbix.

О чем эта статья?

Как следует из названия, в статье предлагается концепция организации мониторинга с высокой доступностью. В роли подопытного выступает Zabbix Server, для организации Active-Active кластера применяется Corosync и Pacemaker, а работает это всё на Linux. Данное ПО является OpenSource, поэтому такое решение доступно каждому.

В процессе эксплуатации Zabbix для мониторинга высоконагруженной ИТ-инфраструктуры (рост количества элементов данных, рост числа узлов сети, большая глубина хранения сырых данных, постоянно растущие потребности пользователей) многие сталкиваются с проблемами производительности сервера Zabbix во время старта или перезапуска. В условиях High Load (>60k NVPS) обычная перезагрузка сервера Zabbix превращается в весьма длительную, хотя и штатную процедуру. Время от запуска службы до появления данных в мониторинге может достигать 15-20 минут.

Столкнувшись с этим, и проанализировав ситуацию, команда мониторинга пришла к решению, что поможет кластеризация по принципу Active-Active. Кроме того, была поставлена цель добиться Disaster Recovery путем переноса на разные ЦОДы.

Задача

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

Существует множество схем и способов как обезопасить сетевую среду сервиса от падения. Команда решила идти по пути адаптации мощной и высоконагруженной системы мониторинга Zabbix к аппаратным и программным возможностями кластеризации, существующим на рынке ИТ-сферы, СберСервис создал кластер высокой доступности. Выбор пал на OpenSource-решения, а точнее на Pacemaker и Corosync.

Требования

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

  • управление нодами ZabbixServer без видимого прерывания сервиса мониторинга на время проведения различных технических работ по обновлению, правке конфигураций и т. д., именно поэтому не подойдет виртуализация в чистом виде;

  • бесшовное переключение трафика между инстансами ZabbixServer в случае выхода из строя одной из нод, желательно автоматически.

Встроенный функционал схемы кластеризации ресурсов в режиме Active-Passive с использованием Pacemaker и Corosync рассматривался уже много раз и в частности на Хабре естьподробная статьядля случая кластеризации БД истатья про кластеризацию Заббикса(вместо Corosync использовался cman, но смысл тот же).

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

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

Полученное решение реализует два важных для системы мониторинга свойства:

  • Непрерывность мониторинга

  • Отказоустойчивость мониторинга

Рассмотрим реализацию решения High Available ZabbixServer в режиме Active-Active без LoadBalancerПринципиальная схема взаимодействия компонентов:

Принцип работы

Использование в схеме менеджера управления кластерными ресурсами (Cluster resource) подразумевает развертывание компонентов управления кластером на виртуальном сервере. Таким образом достигается отказоустойчивость управляющего модуля.

В кластере существует 2 ноды. При подготовке нод следует учитывать свойства stonith и quorum их необходимо отключить.
Свойство quorum применяется для схемы кластера от 3х нод и более. Если в схеме кластера, состоящего из 2х нод использовать данное свойство, тогда при падении одной ноды произойдёт выключение всех ресурсов.

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

ocf::heartbeat:ZBX-IPaddressocf::heartbeat:ZBX-Instance

При аварийном выходе из строя основной ноды, кластерные ресурсы перемещаются на резервную ноду. Ресурс ZBX-IPaddress управляет виртуальным ip-адресом и входит в стандартный набор кластерных ресурсов (IPaddr2). ZBX-Instance самописный кластерный ресурс для сервиса zabbix-server и управления подключениями к БД. На каждом Zabbix-сервере в конфигурационном файле прописаны разные пользователи БД, при этом, в любой момент времени пользователь основного Zabbix-сервера имеет права Read/Write, а пользователь резервного права ReadOnly, поэтому на обеих нодах служба zabbix-server может находиться в запущенном состоянии (привет, Active-Active).

Перевод кластерных ресурсов в случае сбоя выглядит следующим образом. Ресурс ZBX-IP-address переводит виртуальный IP-адрес на другую ноду, а ресурс ZBX-Instance переводит пользователя БД резервного zabbix-сервера в режим Read/Write, а пользователя БД основного zabbix-сервера в режим ReadOnly, при этом закрывая имеющиеся к БД старые сессии подключения. Таким образом мониторинг инфраструктуры не прекращается. Непрерывность записи информации достигается за счет буферизации снятых метрик с объектов мониторинга на стороне ZabbixProxy. После того как прокси получает подключение к серверу, он передает накопленные данные.

Важный нюанс применение данной схемы подходит только в случае нахождения master и slave ZabbixServer-нод в одной подсети.

Рассмотрим реализацию решения High Available ZabbixServer в режиме Active-Active с LoadBalancer

Принципиальная схема взаимодействия компонентов:

Принцип работы

Решение с применением аппаратной балансировки сетевой нагрузки на основе сигнального порта выглядит следующим образом. Аппаратный балансировщик нагрузки отправляет трафик на ноду, на которой доступен сигнальный порт, если порт доступен на обеих нодах, LoadBalancer не будет отправлять трафик на какую-либо из нод. Решение можно использовать, когда ноды кластера находятся в разных подсетях, что позволило развернуть высокодоступный кластер для работы в географически распределенном ЦОД.

В Pacemaker создаются кластерные ресурсы:

ocf::heartbeat:ZBX-Cluster-Socketocf::heartbeat:ZBX-Instance

Ресурс ZBX-Cluster-Socket управляет сигнальным портом на ноде нужен для работы LoadBalancer-а.

Ресурс ZBX-Instance управляет процессом zabbix-server-а и правами доступа к БД.

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

Ресурс ZBX-Cluster-Socket создаётся с помощью встроенной в Pacemaker функциональности по созданию ресурсов из системного процесса (службы). Служба сигнального порта обыкновенная самописная служба, которая просто открывает на хосте соответствующий порт, за состоянием которого будет наблюдать LoadBalancer. Осуществлена привязка ресурса ZBX-Cluster-Socket к ресурсу ZBX-Instance посредством ограничения (constraint) для того, чтобы кластерные ресурсы перемещались совместно. Corosync, управляя ресурсом ZBX-Cluster-Socket, поддерживает в открытом состоянии только порт 101 на основной Master-node и в закрытом состоянии порт 201 на резервной Slave-node. Для LoadBalancer сигналом на переключение/отправку трафика являются: открытый порт 101 на первой ноде или открытый порт 201 на второй ноде, если оба порта на обеих нодах открыты, или оба закрыты, трафик никуда не отправляется.

Переключение ресурсов с текущей Master-node на текущую Slave-node происходит следующим образом:

При падении Master-node, порт 101 становится недоступным, тогда сигналом для LoadBalancer на переключение трафика будет являться открытый порт 201 на Slave-node. Corosync, определив, что Master-node недоступна, переключает ресурсы ZBX-Instance и ZBX-Cluster-Socket вместе на Slave-node, а благодаря скрипту resource_movement, на основе которого Pacemaker создал ресурс ZBX-Instance происходит смена прав пользователей User_A и User_B в базе данных, при этом закрываются все старые сессии подключения к БД.

Что произойдет в случае потери связности между нодами кластера при условии полной работоспособности нод?

Схема та же: кластер состоит из 2-х нод Master-node (пользователь User_A) и Slave-node (User_B), на Master-node запущены кластерные ресурсы.

При потере связи каждая из нод определит, что другая нода недоступна, тогда обе запустят у себя кластерные ресурсы. Master-node перезапускать ничего не будет и продолжит работу, определяя свою роль главной. Slave-node тоже посчитает себя главной и запустит у себя кластерные ресурсы. При этом LoadBalancer определит, что на Master-node и Slave-node доступны порты ZabbixServer и управляющий порт, соответственно LoadBalancer прекратит передачу сетевого трафика.

Следует отметить важный момент какими будут права доступа к базе данных соответствующих пользователей? Одна из нод по-прежнему будет иметь доступ к БД с правами Read/Write, а другая с правами ReadOnly, так как:

  • Если связь Slave-node с БД не была потеряна, то Slave-node во время включения у себя кластерных ресурсов произведет смену прав пользователей: для User_A права изменятся на ReadOnly, а для User_B права изменятся на Read/Write.

  • Если связь Slave-node с БД потеряна, следовательно Slave-node не сможет выполнить переключение прав пользователей.

  • После восстановления связности кластерные ресурсы снова переместятся на Master-node, LoadBalancer определит, что управляющий порт доступен только на Master-node и начнёт передавать ей сетевой трафик.

Заключение

Данный кейс иллюстрирует принципиальную идею и концепцию придуманного решения (а точнее 2-х реализаций), и не является прямым руководством к действию. Инфраструктуры и ограничения у всех разные, а инженеры, перед которыми ставятся похожие задачи не нуждаются в How to.

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

Подробнее..

Ящики, усы и скрипки

18.12.2020 12:07:33 | Автор: admin


Очень часто данные необходимо сравнивать. Например, у нас есть несколько рядов данных из какой-то области деятельности человека (промышленности, медицины, государственного управления, ), и мы хотим сравнить, насколько они похожи или, наоборот, чем одни показатели выделяются по сравнению с другими. Для простоты восприятия возьмем данные более простые, универсальные и нейтральные высоту в холке и вес нескольких пород собак по сведениям Американского клуба собаководства (American Kennel Club). Данные по размерам пород в среднем можно найти здесь. Прибавим к ним функцию random.uniform из Python-библиотеки numpy, переведем дюймы в сантиметры, а фунты в килограммы, и вот мы получаем реалистично выглядящий набор данных по размерам собак нескольких пород, с которым можно работать. В нашем примере это чихуахуа, бигли, ротвейлеры и английские сеттеры.



Одну из аналитик, которую можно применить для сравнения этих 4 числовых рядов посмотреть на их медиану. Она разбивает ряд данных на две части: половина значений меньше медианы и остальная половина больше. Медианные значения находим, группируя с помощью библиотеки pandas по столбцу Порода и применяя к сгруппированным данным функцию median. Аналогично можно было бы посмотреть и другие статистические показатели: среднее значение (mean) и моду (mode).

Видим, что половина встреченных нами чихуахуа имеет высоту в холке не больше 18 см, бигль значительно выше в районе 41 см, и следующие по размерам ротвейлер и английский сеттер, которые отличаются по росту незначительно: 58 и 63 см.



Рисунок 2. Медианные значения высоты в холке четырех пород собак.
Но только одной медианы недостаточно для сравнительного анализа данных. Можно получить больше информации, если рассмотреть такой инструмент как диаграмма размаха (также известная как ящик с усами, box-and-whiskers plot), построенную с помощью Python-библиотеки для построения графиков seaborn. Линия внутри ящика это уже знакомая нам медиана. Ее уровень на графике справа (см. Рисунок 3) совпадает с высотой соответствующего столбца слева. Но при этом диаграмма размаха содержит дополнительную информацию о том, как данные распределены внутри ряда: нижняя граница прямоугольника (ящика) это первый квартиль (величина, превосходящая 25% значений ряда), а верхняя граница третий квартиль (величина, превосходящая 75% значений). А те самые усы отрезки, отходящие вверх и вниз от середины прямоугольника строятся на основе интерквартильного размаха и обозначают верхнюю и нижнюю границу значимой части наших данных, исключая выбросы. Здесь выбросы отсутствуют (дистрофиков и собак-гигантов нам в рассмотрение не попадалось), при наличии они отобразились бы метками за пределами усов.



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



Рисунок 4. Сравнение столбчатой диаграммы, диаграммы размаха и скрипичного графика, построенных для одного и того же набора данных.
Например, зеленым показаны данные о ротвейлерах.

Сходства и различия диаграммы размаха (ящика с усами) и скрипичного графика показаны на следующем Рисунке 5. Сначала сходства: (1) оба графика в том или ином виде отражают 0.25-квантиль, 0.5-квантиль (медиану) и 0.75-квантиль; (2) и там, и там отражаются крайние значения, которые близки к величине полутора межквартильных интервалов (IQR), отложенных от нижнего и верхнего края коробки те самые усы для диаграммы размаха, за пределами которых находятся выбросы.

Отличие же состоит в том, что скрипичный график содержит также информацию о том, как данные распределены внутри, т.к. границы построенной скрипки это повернутая на 90 градусов плотность распределения. И в этом случае при анализе графика у нас гораздо больше информации: в дополнение к квантилям и значениям, описывающим 4 интерквартильных расстояния (1.5 + 1 + 1.5) на скрипичном графике можно увидеть, распределены ли данные равномерно или есть несколько центров, где значения встречаются более часто.



Рисунок5. Пояснения по соответствию элементов двух графиков: размаха и скрипичного.
Более ярко эту мысль можно увидеть на следующем графике (Рисунок 6), где данные по двум группам ротвейлеров отличаются, но подобраны таким образом, что медианы совпадают (крайний слева график) и даже больше диаграммы размаха (в центре) тоже совпадают! И только скрипичный график (крайний справа) показывает нам, что на самом деле структура данных значительно отличается.



Рисунок 6. Пример, когда только скрипичные график позволяет нам увидеть отличия во внутренней структуре рассматриваемых данных.
Используя кластеризацию К-средних (cluster.KMeans) из модуля sklearn, мы можем визуально представить сгруппированные данные, построив диаграмму разброса с помощью функции scatterplot модуля seaborn. Здесь цвет отделяет один кластер, созданный ML-алгоритмом, от другого, а форма маркера показывает исходную принадлежность к той или иной группе. Понижать размерность с помощью PCA или какого-либо другого метода здесь было не нужно, т.к. данные изначально 2D.



Код для кластеризации и построения диаграммы разброса:




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

Thank you points сетевой анализ социальных связей внутри DataArt

07.12.2020 20:14:08 | Автор: admin


Святослав Зборовский из BI-команды DataArt изучил, кого из коллег чаще всего благодарят с помощью корпоративной системы. В статье для Хабр он рассказал, как быстро построить и оптимизировать граф и какие кластеры ему удалось на нем выделить.

Святослав Зборовский, Data Analyst, DataArt

DataArt достаточно крупная IT-компания, в 20 наших офисах в десяти странах работает более 3000 человек. Многие проектные команды распределены по разным городам, взаимодействие между сотрудниками и до начала пандемии COVID-19 чаще всего происходило онлайн. Еще девять лет назад в компании придумали способ дистанционно поблагодарить коллегу с помощью TYPs Thank you points. Типсы аналог внутренней валюты, никак не привязанный к бонусам, зарплатам или стажу. Их можно посылать тем, кто вам помог, получать от тех, для кого что-то хорошее сделали вы сами, и время от времени менять на сувениры: кружки, рюкзаки, пауэрбанки, резиновых уточек и т. д. Если интересно, подробнее о том, как работает система TYPs, можно почитать здесь, но, в общем, это действительно такое спасибо онлайн.


Иллюстрация из статьи о том, как работает типсовая система в DataArt, выходившей осенью 2019 года

Я устроился в компанию год назад. Разобравшись с внутренними системами и, в частности, институтом типсов, я заинтересовался, кого же коллеги обычно благодарят. Правда, многим ли людям отправляют спасибо (ведь количество баллов в распоряжении каждого человека ограничено)? Какие связи и группы внутри системы можно увидеть, оценив обмен типсами? Все дарят всем? Или компания разбита на небольшие кластеры кружки по интересам? Чтобы ответить на эти вопросы, я решил построить сетевой граф.

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

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

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



В качестве инструмента я выбрал Gephi. Использовать его удобнее, чем вручную писать собственную программу на R/Python/ выберите любой язык, позволяющий исследовать сети. Во-первых, в Gephi проще настраивать укладку сети, во-вторых, в нем предусмотрена удобная регулировка размера и цвета текста, что позволяет без лишних усилий облегчить чтение графа.

Первоначальный датасет имел формат таблицы связей и состоял из 46 896 строк отдельных фактов дарения типсов. С 2011 года именно столько раз коллеги официально сказали друг другу спасибо внутри системы учета рабочего времени. Выглядит это примерно вот так:



Поэтому для облегчения графа я применил фильтр degree > 50, другими словами, оставил на нем только коллег, у которых выявлено более 50 связей (фактов дарения или получения типсов).

Поэкспериментировав с укладкой, я остановился на Fruchterman Reingold. Выглядело это вот так:



К отфильтрованному графу я добавил статистику модулярности для выявления кластеров. Их оказалось восемь.

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

Финальная визуализация выглядит так:



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

Голубым цветом (20,61 % всех наблюдений) представлены коллеги из небольшого центра разработки, расположенного в относительно небольшом городе. DataArt там очень сильный игрок на рынке труда, при этом профессиональное сообщество в целом совсем немногочисленно. В этих условиях местный офис занимает в жизни коллег значительное место, и между собой они общаются очень тесно, даже будучи занятыми в разных проектах. Это наглядно отображается в частых спасибо. Лидеры HR-менеджеры, сисадмины, бухгалтеры и самых опытные из инженеров, выступающие менторами для практикантов и активно участвующие в жизни локального центра разработки. Т. е. они проводят вебинары, представляют в офисе результаты своей работы и интересные кейсы, выступают на конференциях с докладами, которые нравятся коллегам. Центральный большой узел инженер хелпдеска.

Зеленый (18.88 %) напротив, коллеги из самого большого (удивительно!) офиса, расположенного в нестоличном городе среднего размера. Однако здесь картина иная: в целом люди реже отправляют друг другу типсы, а я ярко выраженных любимчиков у них попросту нет. Скорее всего, у коллег просто хорошие горизонтальные отношения.[SZ13]

Фиолетовый (18,88 %) менеджеры, которые помогают планировать командировки и считать бюджеты, и участники внутренней BI-команды. У них есть и выраженная категория поклонников, в которую входят менеджеры проектов, деливери менеджеры, тимлиды и синьорные разработчики, которые чаще других выезжают в офисы клиентов.

Черный (15,45 %) это хорошие люди, которых одинаково часто благодарят коллеги самых разных уровней и специализаций. Самые большие черные точки системные администраторы, кроме них, в категорию попадают офис-менеджеры и преподаватели английского.

Оранжевый (11,59 %) объединяет высший менеджмент, HR-менеджеров и тех, кто занимается продвижением компании на рынках труда. Все эти люди развивают бренд DataArt как работодателя и, хотя работают они в разных командах и департаментах, регулярно пересекаются и благодарят друг друга. Эта тенденция прослеживается на протяжении всех девяти лет работы системы, поэтому объединить таких коллег в один кластер вполне логично.

Красным цветом (6,87 %) обозначена еще одна небольшая локация. Самые большие точки два системных администратора и главный HR, действительно много времени уделяющий общению с коллегами и во многом объединяющий их между собой.

Темно-зеленый (3,86%) опять сисадмины, однако не привязанные к определенному офису. Это те, кто помогает настраивать виртуальные окружения, налаживает работу корпоративных систем и консультирует коллег из разных городов и стран. Поэтому и определенной группы, представители которой благодарили бы их чаще других, выявить невозможно. Им в равной степени благодарны все сотрудники компании за это им и полагается отдельный кластер.

Желтый (3,86 %) разработчики внутренних систем Project Manager и EDU, в которых мы ведем учет рабочего времени, следим за динамикой активности в проектах, аккумулируем обучающие курсы и общаемся между собой. Одним словом, в них отражена вся жизнь компании, поэтому тех, кто над ними работает, благодарят достаточно часто, причем коллеги из разных проектов и стран.

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

Граф строился на истории типсовых связей за весь период существования института Thank you points. Если же повторить такое же исследование, но уже на выборке года/полугодия, структура кластеров изменится. Наиболее крупными кластерами окажутся большие проекты, где в выбранном промежутке времени произошел успешный релиз. Остальные кластеры сформируют привычные локальные связи и благодарности менеджерам, сисадминам и учителям английского.

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

Из песочницы Анализ вакансий с использованием кластеризации

22.11.2020 20:18:28 | Автор: admin
В статье приводится метод анализа вакансий по поисковому запросу Python с помощью модели кластеризации Gaussian Mixture Model (GMM). По каждому выделенному кластеру будут приведены наиболее востребованные навыки и диапазон заработных плат.

Для чего проводилось данное исследование? Мне хотелось узнать:

  • В каких прикладных направлениях используется Python
  • Какие требуются знания: базы данных, библиотеки, фреймворки
  • Насколько востребованы специалисты каждого направления
  • Какие зарплаты предлагают



Загрузка данных


Вакансии загружались с сайта hh.ru, с использованием API: dev.hh.ru. По запросу Python было загружено 1994 вакансии (регион Москва), которые были разделены на обучающий и тестовый наборы, в пропорции 80% и 20%. Размер обучающего набора 1595, размер тестового 399. Тестовый набор будет использован только в разделах Топ/Антитоп навыков и Классификация вакансий.

Признаки


По тексту загруженных вакансий были сформированы две группы наиболее часто встречающихся n-грамм слов:

  • 2-граммы на кириллице и латинице
  • 1-граммы на латинице

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

После отбора n-грамм первая группа содержала 81 2-граммы, а вторая 98 1-граммы:
n n-грамма Вес Вакансии
1 2 на python 8 258
2 2 ci cd 8 230
3 2 понимание принципов 8 221
4 2 знание sql 8 178
5 2 разработка и 9 174
... ... ... ... ...
82 1 sql 5 490
83 1 linux 6 462
84 1 postgresql 5 362
85 1 docker 7 358
86 1 java 9 297
... ... ... ... ...

Разбиение вакансий на кластеры было решено сделать по следующим критериям в порядке приоритета:
Приоритет Критерий Вес
1 Сфера (прикладное направление), должность, опыт
n-граммы: машинного обучения, администрирования linux, отличное знание
7-9
2 Инструменты, технологии, программное обеспечение.
n-граммы: sql, ос linux, pytest
4-6
3 Прочие навыки
n-граммы: техническое образование, английского языка, интересные задачи
1-3

Определение к какой группе критериев относится n-грамма, и какой вес ей присвоить, происходило на интуитивном уровне. Приведу пару примеров:
  1. С первого взгляда Docker можно отнести ко второй группе критериев с весом от 4 до 6. Но упоминание Docker в вакансии, скорей всего говорит о том, что вакансия будет на должность DevOps инженер. Поэтому Docker попал в первую группу и получил вес равный 7.
  2. Java тоже попадает в первую группу, т.к. в большинстве рассматриваемых вакансий с присутствием слова Java ищут Java-разработчика с пунктом будет дополнительным преимуществом знание Python. Бывают и вакансии с поиском человека-оркестра. Как первые, так и вторые вакансии меня не интересуют, поэтому их я хочу отделить от остальных вакансий, соответственно присваиваю Java наибольший вес 9.

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

Преобразование данных


Для вычислений каждая вакансия была преобразована в вектор с размерностью 179 (число отобранных признаков) из целых чисел от 0 до 9, где 0 означает что i-ая n-грамма отсутствует в вакансии, а числа от 1 до 9 означают присутствие i-ой n-граммы и ее вес. Далее в тексте под точкой понимается вакансия представленная таким вектором.
Пример:
Допустим список n-грамм содержит всего три значения:
n n-грамма Вес Вакансии
1 2 на python 8 258
2 2 понимание принципов 8 221
3 1 sql 5 490

Тогда для вакансии с текстом.

Требования:

  • Опыт разработки на python от 3-х лет.
  • Хорошее знание sql

вектор равен [8, 0, 5].

Метрика


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

Суть метода в том, чтобы понизить размерность данных, при этом максимально сохранить пропорции расстояний между точками множества. Понять по формулам, как работает t-SNE довольно сложно. Но мне понравился один пример найденный где-то на просторах интернета: допустим у нас есть шарики в трехмерном пространстве. Каждый шарик мы соединяем со всеми остальными шариками невидимыми пружинами, которые никак не пересекаются и не мешают друг другу при пересечении. Пружины действуют в две стороны, т.е. они сопротивляются как отдалению, так и приближению шариков друг к другу. Система находится в стабильном состоянии, шарики неподвижны. Если мы возьмем один из шариков и оттянем его, а затем отпустим то за счет силы пружин он вернется в исходное состояние. Далее мы берем две большие пластины, и сжимаем шарики в тонкий слой, при этом не мешая шарикам двигаться в плоскости между двумя пластинами. Начинают действовать силы пружин, шарики перемещаются и в итоге останавливаются, когда силы всех пружин становятся уравновешенными. Пружины будут действовать так, что шарики, которые находились близко друг к другу, останутся относительно близко и на плоскости. Также и с удаленными шариками они будут удалены друг от друга. С помощью пружин и пластин мы перевели трехмерное пространство в двухмерное, сохранив в каком-то виде расстояния между точкам!

Алгоритм t-SNE использовался мною только для визуализации множества точек. Он помог выбрать метрику, а также подбирать весы для признаков.

Если использовать метрику Евклида, которую мы используем в нашей повседневной жизни, то расположение вакансий будет выглядеть следующим образом:


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

Существует большое множество метрик (способов определения расстояния между двумя точками), которые будут хорошо работать на исследуемых данных. Я выбрал в качестве меры расстояние Жаккара, с учетом весов n-грамм. Мера Жаккара простая для понимания, при этом хорошо работает для решения рассматриваемой задачи.
Пример:
Вакансия 1 содержит n-граммы: на python, sql, docker
Вакансия 2 содержит n-граммы: на python, sql, php
Веса:
на python 8
sql 5
docker 7
php 9
Пересечение множеств (n-грамма встречается в 1-ой и 2-ой вакансии): на python, sql = 8 + 5 = 13
Объединение множеств (все n-граммы из 1-ой и 2-ой вакансии): на python, sql, docker, php = 8 + 5 + 7 + 9 = 29
Расстояние =1 (Пересечение множеств / Объединение множеств) = 1 (13 / 29) = 0.55

Была вычислена матрица расстояний между всеми парами точек, размер матрицы 1595 х 1595. Всего 1 271 215 расстояний между уникальными парами. Среднее расстояние получилось равным 0.96, между 619 659 расстояние равно 1 (т.е. сходства нет совсем). Следующая диаграмма показывает, что в целом вакансии имеют мало сходства:


При использовании метрики Жаккара наше пространство теперь выглядит так:


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

Кластеризация


В качестве алгоритма кластеризации была выбрана модель Gaussian Mixture Model (GMM). Алгоритм получает на вход данные в виде векторов, и параметр n_components число кластеров, на которые надо разбить множество. О том, как работает алгоритм, можно посмотреть здесь (на английском языке). Я использовал готовую реализацию GMM из библиотеки scikit-learn: sklearn.mixture.GaussianMixture.

Отмечу, что GMM не использует метрику, а делает разделение данных только по набору признаков и их весам. В статье расстояние Жаккара используется для визуализации данных, подсчета компактности кластеров (за компактность я принял среднее расстояние между точками кластера), и определения центральной точки кластера (типичная вакансия) точка с наименьшим средним расстоянием до других точек кластера. Многие алгоритмы кластеризации использует именно расстояние между точками. В разделе Другие методы будет рассказано о других видах кластеризаций, которые основываются на метрике и тоже дают хорошие результаты.

В предыдущем разделе на глаз было определено, что кластеров скорей всего будет шесть. Так выглядят результаты кластеризации при n_components = 6:



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

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

Для нахождения оптимального числа кластеров n_components, воспользуемся критериями AIC и BIC, о которых можно прочитать здесь. Расчет данных критериев встроен в метод sklearn.mixture.GaussianMixture. Так выглядит график критериев:


При n_components = 12 критерий BIC имеет наименьшее (наилучшее) значение, критерий AIC тоже имеет значение близкое к минимуму (минимум при n_components = 23). Произведем разделение вакансий на 12 кластеров:



Теперь кластеры имеют более компактные формы, как на вид, так и в числовом выражении. При ручном анализе вакансии оказались разбиты на характерные группы для понимания человека. На рисунке выведены названия кластеров. Кластеры под номерами 11 и 4 помечены как и <Trash 2>:

  1. В кластере 11 все признаки имеют приблизительно одинаковые суммарные веса.
  2. Кластер 4 выделен по признаку Java. Тем не менее вакансий на должность Java Developer в кластере мало, часто знание Java требуется как будет дополнительным плюсом.

Кластеры


После удаления двух неинформативных кластеров под номерами 11 и 4 в итоге получилось 10 кластеров:


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

Обозначения:

S доля вакансий, в которых встречается признак, умноженная на вес признака
% процент вакансий, в которых встречается признак/2-грамма
Типичная вакансия кластера вакансия, с наименьшим средним расстоянием до других точек кластера

Data Analyst


Кол-во вакансий: 299

Типичная вакансия: 35805914
Признак с весом S Признак % 2-грамма %
1 excel 3.13 sql 64.55 знание sql 18.39
2 r 2.59 excel 34.78 в разработке 14.05
3 sql 2.44 r 28.76 python r 14.05
4 знание sql 1.47 bi 19.40 с большими 13.38
5 анализа данных 1.17 tableau 15.38 разработка и 13.38
6 tableau 1.08 google 14.38 анализа данных 13.04
7 с большими 1.07 vba 13.04 знание python 12.71
8 разработка и 1.07 science 9.70 аналитический склад 11.71
9 vba 1.04 dwh 6.35 опыт разработки 11.71
10 знание python 1.02 oracle 6.35 базами данных 11.37

С++ Developer


Кол-во вакансий: 139
Типичная вакансия: 39955360
Признак с весом S Признак % 2-грамма %
1 c++ 9.00 c++ 100.00 опыт разработки 44.60
2 java 3.30 linux 44.60 c c++ 27.34
3 linux 2.55 java 36.69 c++ python 17.99
4 c# 1.88 sql 23.02 на c++ 16.55
5 go 1.75 c# 20.86 разработки на 15.83
6 разработки на 1.27 go 19.42 структур данных 15.11
7 хорошее знание 1.15 unix 12.23 опыт написания 14.39
8 структур данных 1.06 tensorflow 11.51 программирования на 13.67
9 tensorflow 1.04 bash 10.07 в разработке 13.67
10 опыт программирования 0.98 postgresql 9.35 языков программирования 12.95

Linux/DevOps Engineer


Кол-во вакансий: 126
Типичная вакансия: 39533926
Признак с весом S Признак % 2-грамма %
1 ansible 5.33 linux 84.92 ci cd 58.73
2 docker 4.78 ansible 76.19 опыт администрирования 42.06
3 bash 4.78 docker 74.60 bash python 33.33
4 ci cd 4.70 bash 68.25 tcp ip 39.37
5 linux 4.43 prometheus 58.73 опыт настройки 28.57
6 prometheus 4.11 zabbix 54.76 мониторинга и 26.98
7 nginx 3.67 nginx 52.38 prometheus grafana 23.81
8 опыт администрирования 3.37 grafana 52.38 систем мониторинга 22.22
9 zabbix 3.29 postgresql 51.59 с docker 16.67
10 elk 3.22 kubernetes 51.59 управления конфигурациями 16.67

Python Developer


Кол-во вакансий: 104
Типичная вакансия: 39705484
Признак с весом S Признак % 2-грамма %
1 на python 6.00 docker 65.38 на python 75.00
2 django 5.62 django 62.50 разработки на 51.92
3 flask 4.59 postgresql 58.65 опыт разработки 43.27
4 docker 4.24 flask 50.96 django flask 24.04
5 разработки на 4.15 redis 38.46 rest api 23.08
6 postgresql 2.93 linux 35.58 python от 21.15
7 aiohttp 1.99 rabbitmq 33.65 базами данных 18.27
8 redis 1.92 sql 30.77 опыт написания 18.27
9 linux 1.73 mongodb 25.00 с docker 17.31
10 rabbitmq 1.68 aiohttp 22.12 с postgresql 16.35

Data Scientist


Кол-во вакансий: 98
Типичная вакансия: 38071218
Признак с весом S Признак % 2-грамма %
1 pandas 7.35 pandas 81.63 машинного обучения 63.27
2 numpy 6.04 numpy 75.51 pandas numpy 43.88
3 машинного обучения 5.69 sql 62.24 анализа данных 29.59
4 pytorch 3.77 pytorch 41.84 data science 26.53
5 ml 3.49 ml 38.78 знание python 25.51
6 tensorflow 3.31 tensorflow 36.73 numpy scipy 24.49
7 анализа данных 2.66 spark 32.65 python pandas 23.47
8 scikitlearn 2.57 scikitlearn 28.57 на python 21.43
9 data science 2.39 docker 27.55 математической статистики 20.41
10 spark 2.29 hadoop 27.55 алгоритмов машинного 20.41

Frontend Developer


Кол-во вакансий: 97
Типичная вакансия: 39681044
Признак с весом S Признак % 2-грамма %
1 javascript 9.00 javascript 100 html css 27.84
2 django 2.60 html 42.27 опыт разработки 25.77
3 react 2.32 postgresql 38.14 в разработке 17.53
4 nodejs 2.13 docker 37.11 знание javascript 15.46
5 frontend 2.13 css 37.11 и поддержка 15.46
6 docker 2.09 linux 32.99 python и 14.43
7 postgresql 1.91 sql 31.96 css javascript 13.40
8 linux 1.79 django 28.87 базами данных 12.37
9 html css 1.67 react 25.77 на python 12.37
10 php 1.58 nodejs 23.71 проектирования и 11.34

Backend Developer


Кол-во вакансий: 93
Типичная вакансия: 40226808
Признак с весом S Признак % 2-грамма %
1 django 5.90 django 65.59 python django 26.88
2 js 4.74 js 52.69 опыт разработки 25.81
3 react 2.52 postgresql 40.86 знание python 20.43
4 docker 2.26 docker 35.48 в разработке 18.28
5 postgresql 2.04 react 27.96 ci cd 17.20
6 понимание принципов 1.89 linux 27.96 уверенное знание 16.13
7 знание python 1.63 backend 22.58 rest api 15.05
8 backend 1.58 redis 22.58 html css 13.98
9 ci cd 1.38 sql 20.43 умение разбираться 10.75
10 frontend 1.35 mysql 19.35 в чужом 10.75

DevOps Engineer


Кол-во вакансий: 78
Типичная вакансия: 39634258
Признак с весом S Признак % 2-грамма %
1 devops 8.54 devops 94.87 ci cd 51.28
2 ansible 5.38 ansible 76.92 bash python 30.77
3 bash 4.76 linux 74.36 опыт администрирования 24.36
4 jenkins 4.49 bash 67.95 и поддержка 23.08
5 ci cd 4.10 jenkins 64.10 docker kubernetes 20.51
6 linux 3.54 docker 50.00 разработки и 17.95
7 docker 2.60 kubernetes 41.03 опыт написания 17.95
8 java 2.08 sql 29.49 и настройка 17.95
9 опыт администрирования 1.95 oracle 25.64 разработка и 16.67
10 и поддержка 1.85 openshift 24.36 написания скриптов 14.10

Data Engineer


Кол-во вакансий: 77
Типичная вакансия: 40008757
Признак с весом S Признак % 2-грамма %
1 spark 6.00 hadoop 89.61 обработки данных 38.96
2 hadoop 5.38 spark 85.71 big data 37.66
3 java 4.68 sql 68.83 опыт разработки 23.38
4 hive 4.27 hive 61.04 знание sql 22.08
5 scala 3.64 java 51.95 разработка и 19.48
6 big data 3.39 scala 51.95 hadoop spark 19.48
7 etl 3.36 etl 48.05 java scala 19.48
8 sql 2.79 airflow 44.16 качества данных 18.18
9 обработки данных 2.73 kafka 42.86 и обработки 18.18
10 kafka 2.57 oracle 35.06 hadoop hive 18.18

QA Engineer


Кол-во вакансий: 56
Типичная вакансия: 39630489
Признак с весом S Признак % 2-грамма %
1 автоматизации тестирования 5.46 sql 46.43 автоматизации тестирования 60.71
2 опыт тестирования 4.29 qa 42.86 опыт тестирования 53.57
3 qa 3.86 linux 35.71 на python 41.07
4 на python 3.29 selenium 32.14 опыт автоматизации 35.71
5 разработки и 2.57 web 32.14 разработки и 32.14
6 sql 2.05 docker 30.36 тестирования опыт 30.36
7 linux 2.04 jenkins 26.79 опыт написания 28.57
8 selenium 1.93 backend 26.79 тестирования по 23.21
9 web 1.93 bash 21.43 автоматизированного тестирования 21.43
10 backend 1.88 ui 19.64 ci cd 21.43


Зарплаты


Зарплаты указаны только в 261 (22%) вакансии из 1167 попавших в кластеры.

При расчете зарплат:

  1. Если указывался диапазон от и до ..., то использовалось среднее значение
  2. Если указывалось только от ... или только до ..., то это значение и бралось
  3. При расчетах использовалась(или приводились) ЗП после уплаты налогов (NET)

На графике:

  1. Кластеры идут в порядке убывания медианной зарплаты
  2. Вертикальная черта в коробке медиана
  3. Коробка диапазон [Q1, Q3], где Q1 (25%) и Q3 (75%) перцентили. Т.е. в коробку попадают 50% зарплат
  4. В усы попадают зарплаты из диапазона [Q1 1.5*IQR, Q3 + 1.5*IQR], где IQR = Q3 Q1 интерквартильный размах
  5. Отдельные точки аномалии, не попавшие в усы. (Есть аномалии не попавшие и на диаграмму)


Топ/Антитоп навыков


Диаграммы строились по всем 1994 загруженным вакансиям. Зарплаты указаны в 443 (22%) вакансиях. Для расчета по каждому признаку отбирались вакансии, где этот признак присутствует, и на их основе вычислялась медианная ЗП.



Классификация вакансий


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

Такой подход хорошо бы работал (в какой-то мере) для запроса Python. А вот для запроса Программист 1С такой подход работать не будет, т.к. для программистов 1С в наименовании вакансий редко указывают конфигурации 1С или прикладные направления. А направлений где используется 1С много: бухгалтерия, расчет ЗП, расчет налогов, расчет себестоимости на производственных предприятиях, складской учет, бюджетирование, ERP системы, розничная торговля, управленческий учет, и т.д.

Для себя я вижу две задачи по анализу вакансий:

  1. Понять, где используется язык программирования, о котором я мало знаю (как в этой статье).
  2. Фильтровать новые опубликованные вакансии.

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

Если использовать встроенный в sklearn.mixture.GaussianMixture метод predict(), то ничего хорошего не получается. Большинство вакансий он относит к большим кластерам, а два кластера из первых трех являются неинформативными. Я использовал другой подход:

  1. Берем вакансию, которую хотим классифицировать. Векторизуем ее и получаем точку в нашем пространстве.
  2. Рассчитываем расстояние от этой точки до всех кластеров. Под расстоянием между точкой и кластером я принял среднее расстояние от этой точки до всех точек кластера.
  3. Кластер с наименьшим расстоянием и является предсказанным классом для выбранной вакансии. Расстояние до кластера указывает надежность такого предсказания.
  4. Для увеличения точности модели я выбрал расстояние 0.87 как пороговое, т.е. если расстояние до ближайшего кластера больше 0.87, то модель не классифицирует вакансию.

Для оценки модели случайным образом отобраны 30 вакансий из тестового набора. В колонке вердикт:

N/a: модель не классифицировала вакансию (расстояние > 0.87)
+: правильная классификация
-: неправильная классификация
Вакансия Ближайший кластер Расстояние Вердикт
37637989 Linux/DevOps Engineer 0.9464 N/a
37833719 C++ Developer 0.8772 N/a
38324558 Data Engineer 0.8056 +
38517047 C++ Developer 0.8652 +
39053305 Trash 0.9914 N/a
39210270 Data Engineer 0.8530 +
39349530 Frontend Developer 0.8593 +
39402677 Data Engineer 0.8396 +
39415267 C++ Developer 0.8701 N/a
39734664 Data Engineer 0.8492 +
39770444 Backend Developer 0.8960 N/a
39770752 Data Scientist 0.7826 +
39795880 Data Analyst 0.9202 N/a
39947735 Python Developer 0.8657 +
39954279 Linux/DevOps Engineer 0.8398 -
40008770 DevOps Engineer 0.8634 -
40015219 C++ Developer 0.8405 +
40031023 Python Developer 0.7794 +
40072052 Data Analyst 0.9302 N/a
40112637 Linux/DevOps Engineer 0.8285 +
40164815 Data Engineer 0.8019 +
40186145 Python Developer 0.7865 +
40201231 Data Scientist 0.7589 +
40211477 DevOps Engineer 0.8680 +
40224552 Data Scientist 0.9473 N/a
40230011 Linux/DevOps Engineer 0.9298 N/a
40241704 Trash 2 0.9093 N/a
40245997 Data Analyst 0.9800 N/a
40246898 Data Scientist 0.9584 N/a
40267920 Frontend Developer 0.8664 +

Итого: на 12 вакансиях нет результата, на 2 вакансиях ошибочная классификация, на 16 вакансиях правильная классификация. Полнота модели 60%, точность модели 89%.

Слабые стороны


Первая проблема возьмем две вакансии:
Вакансия 1 Ведущий программист C++
Требования:

  • Опыт разработки на C++ от 5-ти лет.
  • Дополнительным плюсом будет знание Python

Вакансия 2 Ведущий программист Python
Требования:
  • Опыт разработки на Python от 5-ти лет.
  • Дополнительным плюсом будет знание C++
С точки зрения модели эти вакансии идентичны. Я пробовал корректировать веса признаков на порядок их нахождения в тексте. Ни к чему хорошему это не привело.

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

Другие методы


На странице cluster comparison хорошо продемонстрированы различные алгоритмы кластеризации. GMM единственный, который дал хорошие результаты.
Остальные алгоритмы либо не работали, либо давали очень скромные результаты.

Из реализованных мной, хорошие результаты были в двух случаях:

  1. Выбирались точки с большой плотностью в некоторой окрестности, стоящие на удаленном расстоянии друг от друга. Точки становились центрами кластеров. Далее на основе центров начинался процесс формирования кластеров присоединение соседних точек.
  2. Агломеративная кластеризация итерационное слияние точек и кластеров. В библиотеке scikit-learn этот вид кластеризации представлен, но работает плохо. В своей реализации я менял матрицу соединений после каждой итерации слияния. Процесс останавливался по достижению некоторых граничных параметров по факту дендрограммы не помогают понять процесс слияния, если кластеризуются 1500 элементов.

Заключение


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

Кластерный анализ каждому

19.01.2021 20:18:31 | Автор: admin

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

Источник изображения: commons.wikimedia.orgИсточник изображения: commons.wikimedia.org

Почему это круто

Кластерный анализ неформально можно определить как разбиение множества объектов так, чтобы похожие объекты попали в одно и то же подмножество, а объекты из разных подмножеств существенно различались. От обычной классификации по заданным признакам кластерный анализ отличается тем, что не алгоритм, а человек выявляет критерий кластеризации данных. Эта задача относится к классу обучения без учителя (англ. unsupervised learning), так как размеченного набора данных или какой-то заведомо известной информации о нём не предоставляется.

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

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

Сравнение применения алгоритмов с параметрами по умолчанию и с настроенными гиперпараметрами.Сравнение применения алгоритмов с параметрами по умолчанию и с настроенными гиперпараметрами.

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

Как определить меру качества

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

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

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

Сравниваем разбиения

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

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

Сравниваем меры качества

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

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

Критерий ранжирования R нормированная функция расстояния между ранжированием разбиений, задаваемым мерой качества, и агрегированным ранжированием разбиений, задаваемым оценками на основе визуального восприятия. Область значения данной функции: [0, 1]; чем значение функции ближе к 0 , тем рассматриваемая мера качества лучше.

Для наглядности давайте рассмотрим пример с собранным мною набором данных из двухсот двумерных наборов данных 2D-200. Для каждого набора данных из 2D-200 были сформированы 14 разбиений. Эти разбиения были оценены пятью асессорами и девятнадцатью мерами качества. В итоге на наборе данных 2D-200 выявлены лучшие меры качества с точки зрения критериев Adq иR.Затем для каждой меры по всем элементам из 2D-200 были вычислены следующие величины:

BestCVI_{Adq} соотношение числа раз, когда мера отвечала критерию адекватности Adq к общему числу экспериментов;

BestCVI_R соотношение числа раз, когда мера была лучшей с точки зрения критерия ранжирования R к общему числу экспериментов.

Значения BestCVI_{Adq} и BestCVI_R для всех мер качества на наборе данных наборов данных 2D-200 представлены в таблице ниже.

Мера

BestCVI_{Adq}

BestCVI_R

Мера

BestCVI_{Adq}

BestCVI_R

DB

0,630

0,000

Sym

0,565

0,123

Dunn

0,665

0,038

CI

0,385

0,006

Silhouette

0,665

0,058

DB*

0,695

0,000

CH

0,675

0,058

gD31

0,730

0,064

S_Dbw

0,640

0,000

gD41

0,735

0,155

SymDB

0,675

0,045

gD51

0,650

0,012

CS

0,475

0,006

gD33

0,715

0,129

COP

0,035

0,000

gD43

0,695

0,168

SV

0,450

0,071

gD53

0,585

0,003

OS

0,035

0,253

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

Однако эффективная рекомендация из девятнадцати мер качества требует значительно большего числа наборов данных, чем представлено в 2D-200. Поэтому я построил множество из четырех самых лучших мер с точки зрения AvgCVI_R среднего значения, вычисляемого на основе критерия ранжирования мер: мера Silhouette, мера Calinski-Harabasz, мера gD41 и мера OS. В таблице приведены значения AvgCVI_R для всех исследованных мной внутренних мер качества.

Мера

AvgCVI_R

Мера

AvgCVI_R

gD41

\mathbf{0,312}

gD53

0,442

gD43

0,314

S_Dbw

0,501

gD33

0,317

Dunn

0,517

OS

\mathbf{0,342}

gD51

0,614

CH

\mathbf{0,369}

CI

0,647

Silhouette

\mathbf{0,370}

CS

0,763

SV

0,370

DB

0,800

Sym

0,380

COP

0,808

gD31

0,380

DB*

0,819

SymDB

0,410

Классификатор, который рекомендует меру качества

Всякий раз производить данные вычисления довольно ресурсозатратно. Можно упростить задачу рекомендации меры качества, если свести её к задаче классификации. И я решил построить классификатор, который для нового набора данных предсказывает, какая из рассматриваемых мер качества будет лучше с точки зрения агрегированных оценок асессоров, если бы они действительно проходили описанный выше тест для этого набора данных. В качестве классификатора я использовал алгоритм случайного леса, который выбрал экспериментально, и который показывает качество классификации F_1 = 0,855. Интересно, что разработанный мета-классификатор сам по себе выступает новой мерой качества, назовём её Meta-CVI.

Как подобрать алгоритм

После того как мера качества известна, я определил два способа получения конечного разбиения, а именно построение эвристического или эволюционного алгоритмов кластеризации. В эвристических алгоритмах содержится неизменяемый критерий качества выстраиваемого разбиения, в эволюционных же критерий качества является гиперпараметром алгоритма. Гиперпараметры это параметры, значения которых задаются до начала обучения, не изменяются в процессе обучения и не зависят от заданного набора данных. Примерами эвристических алгоритмов служат такие алгоритмы, как k-Means, иерархический алгоритм и DBSCAN. Эволюционные алгоритмы осуществляют непосредственный поиск в пространстве возможных разбиений с целью найти оптимальное по задаваемой в качестве параметра мере качества.

Эвристические алгоритмы

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

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

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

Давайте формализуем задачу. Пусть задан некоторый временной бюджет T на поиск лучшего алгоритма A. Требуется разбить его на интервалы T = t_1 + t_2 + . . . + t_m таким образом, что при запуске процессов \pi_j с ограничением по времени t_i получается значение меры качества Q такое, что:

Q(A_{\lambda_j}^{j}) \xrightarrow{(t_1, t_2, \ldots, t_m)} \min_j,

гдеA^j \in A, \lambda = \pi(t_i, A^j, \emptyset),и t_1 + \ldots + t_m = T, t_i \geq 0 \: \forall i.

В этом случае каждой ручке бандита соответствует определённая модель алгоритма кластеризации из конечного множества A вызову ручки i на итерации k процесс оптимизации гиперпараметров этой модели в течение времени t_k. В результате будет достигнуто качество кластеризацииQ(A_{\lambda_i}^{i}, D).

Качество кластеризации определяется с помощью меры, оно и задает награду, получаемую по завершении итерации.

Иллюстрация работы метода выбора и настройки эвристического алгоритма MASSCAH представлена на рисунке ниже:

Эволюционные алгоритмы

Одним из ключевых аспектов работы эволюционных алгоритмов является вычисление функции приспособленности. В нашем случае это внутренняя мера оценки разбиения. Важно научиться быстро её перерасчитывать, если структура кластеров изменилась. Переформулировать задачу можно так: пусть точка x_{id} переместилась из кластера C_a в кластер C_b.

Каким образом можно инкрементально (то есть соответственно каждой новой конфигурации кластеров) перечитывать значение меры вместо того, чтобы вычислять его заново? Поскольку не для всех мер возможен точный инкрементальный перерасчёт за время, меньшее чем полный пересчет, я пересчитывал значение меры приблизительно, когда это невозможно сделать точно.

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

Мера

Полный пересчёт

Инкрементальный пересчёт

Точность пересчёта

Dunn

\mathcal{O}(n^2)

\mathcal{O}(n)

точный пересчёт

CH

\mathcal{O}(n^2 \log(n))

\mathcal{O}(n)

аппроксимация

CI

\mathcal{O}(n \log(n))

\mathcal{O}(n)

аппроксимация

DB

\mathcal{O}(n \log(n))

\mathcal{O}(n)

аппроксимация

Sil

\mathcal{O}(n^2)

\mathcal{O}(n)

точный пересчёт

gD31

\mathcal{O}(n^2)

\mathcal{O}(n)

точный пересчёт

gD33

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

gD41

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

gD43

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

gD51

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

gD53

\mathcal{O}(n \log(n))

\mathcal{O}(n)

аппроксимация

CS

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

DB*

\mathcal{O}(n \log(n))

\mathcal{O}(n)

аппроксимация

Sym

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

SymDB

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

COP

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

SV

\mathcal{O}(n^2)

\mathcal{O}(n)

аппроксимация

OS

\mathcal{O}(n^2 \log(n))

\mathcal{O}(n)

аппроксимация

S_Dbw

\mathcal{O}(n \log(n))

\mathcal{O}(n)

аппроксимация

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

Эволюционный алгоритм кластеризации (1+1).Эволюционный алгоритм кластеризации (1+1).

Принимая во внимание эту особенность, я придумал мета-классификатор, рекомендующий список мутаций для решаемой задачи кластеризации. По всем запускам алгоритма с равновероятно выбираемыми мутациями для каждого из используемых набора данных я посчитал степень полезности каждой мутации. Для каждого запуска алгоритма построил распределение, которое показывало, какое число раз та или иная мутация давала прирост с точки зрения функции приспособленности на каждой итерации. Потом я взял пять лучших мутаций и построил бинарный вектор, где лучшим мутациям соответствовала 1, а остальным 0 . Мета-признаковое описание каждого набора данных аналогично тому, которое использовалось мной для построения классификатора, предсказывающего меру качества. Таким образом был построен мета-классификатор, позволяющий для каждого набора данных рекомендовать набор мутаций, который нужно использовать в(1 + 1)алгоритме.

Ниже представлена таблица числа запусков алгоритма (1+1) с автоматизацией и без неё, сгруппированная по оптимизируемым мерам качества. Хуже и не хуже означает, что автоматизированный алгоритм, соответственно, отстаёт либо не отстаёт от алгоритма без автоматической настройки параметров по качеству разбиений; t_a, t_p среднее время работы алгоритма с автоматизацией и без неё соответственно.

Calinski-Harabasz

OS

gD41

Silhouette

хуже

не хуже

хуже

не хуже

хуже

не хуже

хуже

не хуже

t_p>t_a

1

6

2

46

2

32

4

15

t_p<t_a

18

72

5

44

16

47

20

58

Сравнение алгоритмов

Интересно сравнить алгоритм на основе выбора и настройки эвристических алгоритмов кластеризации MASSCAH с алгоритмом настройки эволюционного (1+1) алгоритма кластеризации.

Я предположил, что два алгоритма получают одинаковые значения меры качества, если интервалы этих значений [ - , + ] пересекаются. То есть была использована квантиль уровня 84,13\% для нормального распределения. Временной бюджет алгоритма, запускаемого на определённых мере и наборе данных, задавался равным среднему времени работы автоматизированного эволюционного алгоритма на этих мере и наборе данных. Я запустил алгоритмы со всеми отобранными ранее четырьмя мерами качества: Silhouette, Calinski-Harabasz, gD41 и OS. Для каждой пары мера набор данных производилось 10 запусков алгоритма. Полученные количества удачных и неудачных запусков приведены в таблице ниже.

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

MASSCAH > Evo

MASSCAH \approx Evo

MASSCAH < Evo

Мера CH

11

50

36

Мера OS

9

65

23

Мера Silhouette

12

72

13

Мера gD41

4

76

17

Все меры

36

263

89

Мера Meta-CVI

13

68

16

Можно заметить, что успешность эволюционного алгоритма зависит от используемой меры, но по общему числу запусков он сравним с предложенным методом выбора и настройки гиперпараметров эвристического алгоритма кластеризации. Отдельно стоит заметить, что эволюционный алгоритм кластеризации с автоматически настраиваемыми параметрами опережает таковой без автоматической настройки параметров по измеренным характеристикам независимо от меры, однако при этом его производительность по сравнению с разработанным методом на основе обучения с подкреплением зависит от выбора меры оценки качества разбиения. Кроме того, расчёт числа удачных и неудачных запусков производился для предложенной мной меры Meta-CVI.

Как применить всё это на практике

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

Схема описания работы программного комплекса.Схема описания работы программного комплекса.

Этот программный комплекс состоит из нескольких пакетов. Пакет CVI_Predictor реализует алгоритм предсказания меры для конкретной задачи кластеризации на основе мета-обучения. Пакет RL_Clustering реализует различные алгоритмы на базе представленного в работе метода выбора и настройки эвристического алгоритма кластеризации. Пакет Evo_Clustering реализует эволюционный алгоритм кластеризации с параметрами, настраиваемыми при помощи мета-обучения. Пакет Incremental_CVI реализует инкрементальное вычисление мер качества разбиений. Весь комплекс можно скачать на GitHub.

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

На сегодняшний день система автоматического выбора и оценки алгоритмов кластеризации и их параметров была успешно использована в рамках государственного задания 2.8866.2017/8.9 Технология разработки программного обеспечения систем управления ответственными объектами на основе глубокого обучения и конечных автоматов. В рамках этого задания решалась задача нахождения формальной грамматики по некоторому конечному списку слов, которые принадлежат некоторому неизвестному формальному языку. В частности, была решена важная подзадача разметки слов-примеров, по которым строится грамматика при помощи рекуррентных нейронных сетей.

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

Помимо этого, программный комплекс был применён для разработки рекомендательной системы выбора научного руководителя и темы исследования для абитуриентов Университета ИТМО.

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

Подробнее..

Анализ колоса пшеницы методами компьютерного зрения. Определение плоидности

19.08.2020 12:13:25 | Автор: admin
14-ого августа завершился первый воркшоп Математического центра в Академгородке. Я выступал в роли куратора проекта по анализу колоса пшеницы методами компьютерного зрения. В этой заметке хочу рассказать, что из этого вышло.

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

image

Описание данных


Для решения задачи еще до начала воркшопа был подготовлен набор данных, в котором для каждого вида растения была известна плоидность. Всего в нашем распоряжении оказалось 2344 фотографии гексаплоидов и 1259 тетрапроидов.

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

image

Всего 3603 фото с 644 уникальными посевными номерами. В наборе данных представлено 20 видов пшениц: 10 гексаплоидных, 10 тетраплоидных; 496 уникальных генотипов; 10 уникальных вегетаций. Растения были выращены в период с 2015 по 2018 годы в теплицах ИЦиГ СО РАН. Биологический материал предоставлен академиком Николаем Петровичем Гончаровым.

Валидация


Одному растению в нашем наборе данных может соответствовать до 5 фотографий, снятых по разным протоколам и в разных проекциях. Мы разделили данные на 3 стратифицированные подборки: train (обучающая выборка), valid (валидационная выборка) и hold out (отложенная выборка), в соотношениях 60%, 20% и 20% соответственно. При разбиение мы учитывали, что бы все фотографии определенного генотипа всегда оказывались в одной подвыборке. Данная схема валидации использовалась для всех обучаемых моделей.

Пробуем классический CV и ML методы


Первый подход, который мы использовали для решения поставленной задачи основан на существующем алгоритме разработанным нами ранее. Алгоритм из каждого изображения позволяет извлечь фиксированный набор различных количественных признаков. Например, длина колоса, площадь остей и т.д. Подробное описание алгоритма есть в статье Genaev et al., Morphometry of the Wheat Spike by Analyzing 2D Images, 2019. Используя данный алгоритм и методы машинного обучения, нами были обучены несколько моделей для предсказания типов плоидности.

image

Мы использовали методы логистической регрессии, случайный лес и градиентный бустинг. Данные были предварительно нормированы. В качестве меры точности мы выбрали AUC.

Метод Train Valid Holdout
Logistic Regression 0.77 0.70 0.72
Random Forest 1.00 0.83 0.82
Boosting 0.99 0.83 0.85


Лучшую точность на отложенной выборке показал метод градиентного бустинга, мы использовали реализацию СatBoost.

Интерпретируем результаты


Для каждой модели мы получали оценку важности каждого признака. В результате получили список всех наши признаков, ранжированный по значимости и отобрали топ 10 признаков: Awns area, Circularity index, Roundness, Perimeter, Stem length, xu2, L, xb2, yu2, ybm. (описание каждого признака можно посмотреть тут).
Примером важных признаков являются длина колоса и его периметр. Их визуализация показана на гистограммах. Видно, что гексаплоидные растения по характеристикам размера больше,
чем тетраплоидные.
image

Мы выполнили кластеризацию топ 10 признаков методом t-SNE

image

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

Для подтверждения нашей гипотезы о большей фенотипической изменчивости у гексаплоидов мы применили F статистку. F статистика дает значимость различий дисперсий двух распределений. Опровержением нулевой гипотезы о том, что не существует различий между двумя распределениями мы считали случаи, когда значение p-value меньше 0.05. Мы провели этот тест независимо для каждого признака. Условия проверки: должна быть выборка независимых наблюдений (в случае нескольких изображений это не так) и нормальность распределений. Для выполнения этих условий мы проводили тест по одному изображению каждого колоса. Брали, фотографии только в одной проекции по протоколу table. Результаты показаны в таблице. Видно, что дисперсия для гексоплоидов и тетраплоидов имеет значимые различия для 7 признаков. Причем во всех случаях значение дисперсии выше у гексоплоидов. БОльшую фенотипическую вариабельность у гексаплоидов можно объяснить большим числом копий одного гена.

Name F-statistic p-value Disp Hexaploid Disp Tetraploid
Awns area 0.376 1.000 1.415 3.763
Circularity index 1.188 0.065 0.959 0.807
Roundness 1.828 0.000 1.312 0.718
Perimeter 1.570 0.000 1.080 0.688
Stem length 3.500 0.000 1.320 0.377
xu2 3.928 0.000 1.336 0.340
L 3.500 0.000 1.320 0.377
xb2 4.437 0.000 1.331 0.300
yu2 4.275 0.000 2.491 0.583
ybm 1.081 0.248 0.695 0.643


В наших данных представлены растения 20 видов. 10 гексоплоидных пшениц и 10 тераплоидных.
Мы разукрасили результаты кластеризации так, что бы цвет+форма каждой точки соответствует определенному виду.
image

Большинство видов занимает достаточно компактные области на графике. Хотя эти области могут сильно перекрываться с другими. С другой стороны, внутри одного вида могут быть четко выраженные кластеры, например как для T compactum, T petropavlovskyi.

Мы усредняли значения для каждого вида по 10 признакам, получив таблицу 20 на 10. Где каждому из 20 видов соответствует вектор из 10-ти признаков. Для этих данных построили матрицу корреляции и провели иерархический кластерный анализ. Синие квадраты на графике соответствуют тетраплоидам.
image

На построенном дереве, в общем, виды пшениц разделись на тетраплоидные и гексаплоидные. Гексаплоидные виды четко разделисись на два кластера среднеколосые T. macha, T.aestivum, T. yunnanense и длинноколосые T. vavilovii, T. petropavlovskyi, T. spelta. Исключение к гексаплоидным попал единственный дикий полиплоидный (тетраплоидный) вид T. dicoccoides.
В то время как в тетраплоидные виды попали гексаплоидные пшеницы с компактным типом колоса T. compactum, T. antiquorum и T. sphaerococcum и рукотворная изогенная линия АНК-23 мягкой пшеницы.

Пробуем CNN


image
Для решения задачи определения плоидности пшеницы по изображению колоса мы обучили сверточную нейронную сеть архитектуры EfficientNet B0 с предобученными на ImageNet весами. В качестве loss функции использовали CrossEntropyLoss; оптимизатор Adam; размер одного батча 16; изображения ресайзили до разрешения 224x224; скорость обучения меняли, согласно стратегии fit_one_cycle с начальным lr=1e-4. Обучали сеть в течении 10 эпох, накладывая случайным образом следующие аугментации: повороты на -20 +20 градусов, изменение яркости, контрастности, насыщенности, зеркальное отображение. Лучшею модель выбирали по метрике AUC, значение которой считалось в конце каждой эпохи.

В результате точность на отложенной выборке AUC=0.995, что соответствует accuracy_score=0.987 и ошибки равной 1.3%. Что является очень не плохим результатом.

Заключение


Эта работа является удачным примером того, как силами коллектива из 5 студентов и 2-ух кураторов в течении нескольких недель можно решить актуальную биологическую задачу и получить новые научные результаты.
Я хотел бы выразить благодарность всем участникам нашего проекта: Никита Прохошин, Алексей Приходько, Андреевич Евгений, Артем Пронозин, Анна Паулиш, Евгений Комышев, Михаил Генаев.
Николаю Петровичу Гончарову и Афонникову Дмитрию Аркадьевичу за предоставленный биологический материал и помощь в интерпретации результатов.
Математическому центру Новосибирского Государственного Университета и Институту Цитологии и Генетики СО РАН за организацию мероприятия и вычислительные мощности.
image

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

Как мы на хакатоне транспорт кластеризировали

30.03.2021 20:09:12 | Автор: admin

Привет, Хабр! Компьютерное зрение и искусственный интеллект одни из самых востребованных направлений в современном IT. Поэтому мы выбрали именно их для учебного"Межгалактического Хакатона 2021"который организовали НИТУ МИСиС и Zavtra.Online (подразделение SkillFactory по работе с университетами).

В хакатоне были представлены 5 кейсов от разных компаний, и одним из них был кейс от компании IntelliVision кластеризация изображений транспортных средств. Его и выбрала команда финалистов, описав реализацию подобного проекта от А до Я.


Начало работы

Целью любого кластерного анализа является поиск существующих структур. Так и в нашей задаче были даны изображения, которые нужно разбить на кластеры и интерпретировать каждый из них. В качестве исходных данных нам предоставили изображения транспортных средств разных типов, цветов, ракурсов и деталей. Исходные изображения были загружены в нейронную сеть, которая определила паттерны и построила модель, и эта модель отображается в виде вектора (дескриптора), полученного на промежуточном (скрытом) слое нейронной сети. Варианты дескрипторов, полученные с помощью глубокого обучения, были исходными данными для дальнейшей кластеризации: color_model, osnet, efficientnet-b7, type_model.

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

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

Особенности выполнения задания

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

Сначала проводилась работа по понижению размерности данных для увеличения скорости обучения моделей, но PCA давал малоинформативные результаты, а t-SNE из библиотеки scikit-learn имел низкую производительность. И тут на помощь пришёлRapids бесплатный open-source фреймворк для ускорения обработки данных от NVIDIA, в котором есть библиотека машинного обучения cuML. Задача была решена в Jupyter Notebook в Google Colab, так как в эту среду легко установитьRapids, а также использовать его совместно с GPU Tesla K80 с 13 Гб видеопамяти на борту.

Исследование набора данных color_model

Этот набор данных в виде csv файла из 416314 строк и 128 столбцов был получен при помощи модели регрессии для определения цвета транспортных средств в формате RGB. Это единственный набор, который было возможно использовать для проведения экспериментов без понижения размерности.

Кандидатами в лучшее число кластеров на основе метода локтя оказались 3 и 4.

По визуализации результатов кластеризации (кандидаты в лучшие кластеры) для стандартизированных и нормированных данных видно, что предобработка данных повлияла на результат кластеризации. Разделение на 2 и 3 кластера почти одинаковое вне зависимости от способа обработки данных, но есть разница в разбиении на 4 кластера.

Это увеличенные результаты кластеризации на данных, размерность которых была понижена при помощи t-SNE. Видно, что алгоритм пытается выделять кластеры и один из них синий отделил успешно, но в целом чёткой границы нет.

По итогам экспериментов мы визуализировали случайные картинки для каждого из результатов разбиения на 2, 3, 4 кластера.

Видно, что в зависимости от потребностей при 2-х, 3-х и 4-х кластерах вне зависимости от типа обработки можно получить кластеры:

[Светлый-Тёмный],

[Светлый-Тёмный-Цветной],

[Светлый-Серый-Тёмный-Цветной]

А что же другие алгоритмы? Мы попробовали также DBSCAN, и у него получилось выделить отдельно выбросы фото низкого качества. Это фото с включёнными фарами, вблизи и сзади. Интересный эффект кластер жёлтых автомобилей.

Видно, что, комбинируя K-means и DBSCAN, можно в зависимости от потребностей получить разбивку на цветовые кластеры с различной детализацией, а также выделить выбросы.

Исследование набора данных osnet

Следующим набором дескрипторов, на котором мы провели исследования, сталosnet.

Из условий задачи нам было известно, что для построения дескрипторов osnet использовалась нейронная сеть, обученная для повторной идентификации людей, животных и машин (reID). В отличие от type_model и color_model эта модель не обучалась на исходном датасете veriwild.

В связи с этим мы предположили, что модель, обученная на наборе дескрипторов osnet, должна объединять в кластеры объекты не только по цвету и типу транспортных средств, но и по другим признакам (например, ракурсу съёмки).

В связи большим размером данныхosnet(csv файл из 416314 строк и 512 столбцов) и ограниченности имеющихся вычислительных мощностей и сроков все эксперименты проводились на предобработанных данных с пониженной при помощи t-SNE размерностью.

Помимо простого алгоритма k-Means мы решили проверить Mini-Banch k-Means. Как и ожидалось, Mini-Banch k-Means справился быстрее, но качество кластеризации, показанное простым k-Means, оказалось лучше.

Как и на других наборах данных, оптимальное число кластеров определяли с помощьюметода локтя.Оптимальными кандидатами являются 3-й и 4-й кластеры.

После стандартизации данных на диаграмме визуально определялось более чёткое разбиение на кластеры, но друг от друга кластеры не были изолированы.

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

В результате мы увидели, что при увеличении количества кластеров модель старается разделить выборку одновременно по цвету автомобиля и ракурсу съёмки.

Также мы увидели, что модель не разделила транспортные средства на отдельные кластеры в зависимости от типа: седан/джип/грузовик/автобус. Можно предположить, что другие параметры кластеризации позволят улучшить качество такого разбиения.

Особый интерес представляет способность модели выделять нестандартные кластеры. К примеру, нам показалось, что в одном из экспериментов модель выделила в отдельный кластер объекты с бликами и пятнами:

Исследование набора данных efficientnet-b7

Следующим этапом исследования было исследование работы модели на дескрипторе Efficientnet-b7. Этот дескриптор был самым большим по размеру (416314, 2560), данная модель классификации изображений обучена на Imagenet и до этой работы данных из veriwild не видела.

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

Далее модель быластандартизированаинормализована. Построенная после этого двухмерная визуализация, не разделённая на кластеры, выявила небольшие различия:

Затем кластеризовали данные на 2, 3, 4, 20 кластеров методом k-Means, как показавшим лучшие результаты на предыдущих моделях, описанных выше.

Аналогично описанию выше было определено исследуемое количество кластеров с помощью Elbow method clistering (метод локтя):

В силу схожей природы индекса Дэвиса Болдуина (ДБ) и метода локтя в данном исследовании взят индекс ДБ с его локтями в точках 9 и 20. Для того чтобы компенсировать недостаток данного индекса, заключающийся во влиянии масштаба данных на значение индекса, применена нормализация данных перед исследованием (craftappmobile.com).

Визуализация для нормализованной модели:

Результаты кластеризации (в виду большого числа картинок, все под спойлерами):

3 кластера
Кластер 0 светлые машины, задом.Кластер 0 светлые машины, задом.Кластер 1 тёмные машины.Кластер 1 тёмные машины.Кластер 2 светлые машины, передом.Кластер 2 светлые машины, передом.
4 кластера попытка разделить на светлые/тёмные зад/перед
Кластер 0 светлые машины, передом.Кластер 0 светлые машины, передом.Кластер 1 тёмные машины, передом.Кластер 1 тёмные машины, передом.Кластер 2 светлые машины, задом много выбросов.Кластер 2 светлые машины, задом много выбросов.Кластер 3 тёмные машины, задом много выбросов.Кластер 3 тёмные машины, задом много выбросов.
9 кластеров попытка разделить на светлые/тёмные зад/перед ракурс тип кузова по цвету
Кластер 0 светлые машины, передом, ракурс направо, внедорожник (вэн) много выбросов.Кластер 0 светлые машины, передом, ракурс направо, внедорожник (вэн) много выбросов.Кластер 1 тёмные машины, задом, ракурс влево много выбросов. Кластер 1 тёмные машины, задом, ракурс влево много выбросов. Кластер 2 светлые машины, задом, ракурс влево.Кластер 2 светлые машины, задом, ракурс влево.Кластер 3 светлые машины, задом, ракурс вправо, внедорожник (вэн) много выбросов.Кластер 3 светлые машины, задом, ракурс вправо, внедорожник (вэн) много выбросов.Кластер 4 синие машины, передом, ракурс вправо.Кластер 4 синие машины, передом, ракурс вправо.Кластер 5 белые машины, передом, ракурс вправо, внедорожник (вэн).Кластер 5 белые машины, передом, ракурс вправо, внедорожник (вэн).Кластер 6 белые машины, задом, ракурс вправо, седан много выбросов.Кластер 6 белые машины, задом, ракурс вправо, седан много выбросов.Кластер 7 белые машины, передом, ракурс вправо, седан много выбросов.Кластер 7 белые машины, передом, ракурс вправо, седан много выбросов.Кластер 8 тёмные машины, передом, ракурс вправо много выбросов.Кластер 8 тёмные машины, передом, ракурс вправо много выбросов.
20 кластеров разделение по цвету зад/перед ракурс тип кузова
Кластер 0 красный, передом, влево много выбросов из-за сливающегося цвета фар.Кластер 0 красный, передом, влево много выбросов из-за сливающегося цвета фар.Кластер 1 т.-серый, перед, вправо, кроссовер.Кластер 1 т.-серый, перед, вправо, кроссовер.Кластер 2 синий, зад, вправо много выбросов.Кластер 2 синий, зад, вправо много выбросов.Кластер 3 белый, перед, вправо нет ошибок, кузов определён неточно: хэтчбек/кроссовер.Кластер 3 белый, перед, вправо нет ошибок, кузов определён неточно: хэтчбек/кроссовер.Кластер 4 св.-серый, зад, вправо, седан.Кластер 4 св.-серый, зад, вправо, седан.Кластер 5 т.-серый/чёрный, перед, влево, кроссовер.Кластер 5 т.-серый/чёрный, перед, влево, кроссовер.Кластер 6 белый, зад, вправо, кроссовер.Кластер 6 белый, зад, вправо, кроссовер.Кластер 7 белые, перед, вправо, седан.Кластер 7 белые, перед, вправо, седан.Кластер 8 белый, зад, влево, кроссовер.Кластер 8 белый, зад, влево, кроссовер.Кластер 9 т.-серый, перед, вправо, седан.Кластер 9 т.-серый, перед, вправо, седан.Кластер 10 т.-серый, зад, вправо, седан.Кластер 10 т.-серый, зад, вправо, седан.Кластер 11 св.-серый, перед, влево, вэн. Кластер 11 св.-серый, перед, влево, вэн. Кластер 12 св.-серый, перед, вправо, вэн.Кластер 12 св.-серый, перед, вправо, вэн.Кластер 13 белый, перед, вправо, седан.Кластер 13 белый, перед, вправо, седан.Кластер 14 т.-серый/чёрный, перед, влево, седан смешан с кластером 5.Кластер 14 т.-серый/чёрный, перед, влево, седан смешан с кластером 5.Кластер 15 белый, перед, влево, седан.Кластер 15 белый, перед, влево, седан.Кластер 16 т.-серый, зад, влево, седан.Кластер 16 т.-серый, зад, влево, седан.Кластер 17 св.-серый, перед, вправо, кроссовер.Кластер 17 св.-серый, перед, вправо, кроссовер.Кластер 18 чёрный, перед, вправо, кроссовер много выбросов.Кластер 18 чёрный, перед, вправо, кроссовер много выбросов.Кластер 19 чёрный, перед, вправо, седан.Кластер 19 чёрный, перед, вправо, седан.

Выводы:

  1. Модель кластеризации с 20 кластерами, определёнными методом локтя с помощью индекса Дэвиса Болдуина показала себя лучше, чем модели с меньшим количеством кластеров, и в целом достаточно информативно.

  2. После кластеризации стало заметно, что стандартизированная модель кластеризует заметно с большим количеством ошибок, чем нормализованная.

  3. Ошибок в кластере не более 33 % (3 из 9), но чаще 22 % (2 из 9), при этом всего кластеров с ошибками 40 % (8 из 20).

  4. Следует отметить, что модель плохо различает данные (фотографии), когда фары и машина одного цвета: происходит больше ошибок.

  5. Для упрощения работы с моделью можно применять методы уменьшения размерности, в частности, t_SNE показал лучший результат уменьшив размерность с (416314, 2560) до (416314, 2), что позволило использовать значительно меньшие мощности вычисления и получить вполне интерпретируемый результат.

  6. Более подробного анализа выбросов в данном разделе не производилось.

Исследование набора данных type_model

Набор данных в виде csv файла, имеющего 416314 и 512 столбцов, был получен при помощи модели определения типа, и в целом работа с ним была аналогична работе с набором color.

Кандидатами в лучшее число кластеров на основе метода локтя оказался случай с 6 кластерами. При этом расчёты и визуализации также осуществлялись для большего и меньшего числа кластеров

Кластеризация проводилась как на стандартных, так и на нормированных данных.

Как и в случае с набором данных color, результаты кластеризации на данных, размерность которых была понижена при помощи t-SNE, целом не дают чёткого деления на кластеры.

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

В случае с 3 кластерами, несмотря на относительно чёткое разделение, значимой кластеризации добиться не удалось. Нормированные данные дают некоторое разделение по размеру автомобилей.

Кластер 0 седаны (небольшие авто),
Кластер 1 кроссоверы (джипы),
Кластер 2 микроавтобусы, автобусы (крупные авто).

В случае с 6 кластерами их условно можно идентифицировать следующим образом:

Кластер 0 седаны (вид спереди).
Кластер 1 джипы, хэтчбеки.
Кластер 2 мини-вэны.
Кластер 3 седаны (вид сзади).
Кластер 4 грузовики.
Кластер 5 хэтчбеки.

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

Заключение

Несмотря на крайне сжатые сроки, поставленная задача была выполнена, и были получены интерпретируемые результаты, которые можно использовать в дальнейшей работе. У кого будут добавления смело делитесь ими в комментариях. Прилагаем ссылку на репозиторий вGitHub, а итоговый файл с разметкой кластеров расположен в репозитории и доступен поссылке.

Участники командыCloud_9:

  • Екатерина Лушпина Team Leader / презентация / коммуникация / статья;

  • Анастасия Сухоносенко Product Manager / план исследования / код-фреймворк / презентация / статья;

  • Александр Кудрявцев Speaker, Team Member / исследование / презентация / спикер / статья;

  • Наталья Авдеева Team Member / исследование / презентация / статья;

  • Павел Озернов Team Member / исследование / техническая поддержка / презентация / статья.

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

Примечание редактора

Если в вашей компании есть кейcы по Data Science, которые вы бы хотели решить в рамках хакатона или стать ментором пишите в личные сообщенияskillfactory_school. Также мы будем рады индустриальным партнёрам для наших программ и можем предложить им разные виды сотрудничества: членство в наблюдательном совете, экспертиза для создания курсов, стажировки в ваших компаниях для студентов и другие виды партнёрства. Давайте развивать Data Science вместе!

Узнать больше про нашу магистратуру можно на сайтеdata.misis.ruи вTelegram-канале.

Ну, и, конечно, не магистратурой единой!.. Хотите узнать больше проData Science,машинное и глубокое обучение заглядывайте к нам на соответствующие курсы; будет непросто, но увлекательно.

Узнайте, как прокачаться в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

Перевод Facebook Prophet Deep Learning NeuralProphet

04.05.2021 18:23:50 | Автор: admin

Улучшение интерпретируемой модели Prophet с помощью глубокого обучения

Привет, хабровчане. В рамках набора учащихся на онлайн-курс "Machine Learning. Advanced" подготовили перевод материала.

Приглашаем всех желающих поучаствовать в открытом демо-уроке Кластеризация временных рядов: интереснейшая задача, которую можно прикрутить к временным рядам.
Можно ли найти похожие друг на друга по динамике финансовые активы на бирже?
Как сгруппировать пользователей по их поведению?
Кто подставил кролика Роджера?
Ответы на некоторые из этих вопросов мы получим на онлайн-занятии. Присоединяйтесь!


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

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

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

NeuralProphet

Чтобы понять, что такое NeuralProphet, я кратко рассмотрю ее составные части и объясню, как все они складываются воедино.

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

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

Источник

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

  • Prophet может использовать дополнительные внешние регрессоры т.е. не только лаговые значения цели

  • модель может учитывать эффект праздников

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

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

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

  • настройка гиперпараметров, безусловно, не так проста, как в параметрических моделях

  • нейронные сети зачастую считаются моделями черного ящика, другими словами, очень близкими к неинтерпретируемым (хотя есть много исследований направленных на решение этой проблемы)

Как упоминалось во введении, основными преимуществами использования Prophet являются хорошая производительность, интерпретируемость, а также простота установки и использования. Именно на это авторы NeuralProphet ориентировались в разработке своей библиотеки сохранить все преимущества Prophet, улучшив при этом его точность и масштабируемость за счет внедрения улучшенного бэкенда (PyTorch вместо Stan) и использования авторегрессионной сети (AR-Net), чтобы объединить масштабируемость нейронных сетей с интерпретируемостью авторегрессионных моделей. Если охарактеризовать AR-Net одним предложением, то это однослойная сеть, которая обучена имитировать авторегрессионный процесс в сигнале временного ряда, но в гораздо большем масштабе, чем традиционные модели.

NeuralProphet против Prophet

Кратко описав, что такое NeuralProphet, я хотел бы сосредоточиться на различиях между двумя библиотеками. Если опираться на документацию, то основные отличия заключаются в следующем:

  • NeuralProphet в целях оптимизации использует градиентный спуск PyTorch, что значительно ускоряет моделирование

  • Автокорреляция временных рядов моделируется с использованием авторегрессионной сети.

  • Лаговые регрессоры моделируются с использованием отдельной нейронной сети прямого распространения.

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

  • Модель настраивается на определенные горизонты прогноза (больше 1).

  • Она предлагает настраиваемые потери и метрики.

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

Установка

На момент написания, лучший способ установить NeuralProphet это клонировать репозиторий и установить ее прямо оттуда, запустив pip install. в каталоге. Самую актуальную информацию о процедуре установки см. в этой части инструкции.

Установив библиотеки, импортируем их в Python.

import pandas as pdfrom fbprophet import Prophetfrom neuralprophet import NeuralProphetfrom sklearn.metrics import mean_squared_error# plottingimport matplotlib.pyplot as plt# settingsplt.style.use('seaborn')plt.rcParams["figure.figsize"] = (16, 8)

neural_prophet_1.py hosted with by GitHub

Подготовка данных

В этом примере мы будем работать с набором данных Peyton Manning (звезда НФЛ). Если вы не американец, вам, вероятно, придется заглянуть в статью в Википедии, чтобы понять шутку в документации к Prophet. Но вернемся к нашей теме набор данных содержит лог ежедневных просмотров его странички в Википедии.

Набор данных был собран командой Facebook, чтобы показать, как работает Prophet, и доступен для использования как в Prophet, так и в NeuralProphet.

Мы загружаем данные, выполнив следующую строку:

# loading the datasetdf = pd.read_csv('../neural_prophet/example_data/wp_log_peyton_manning.csv')print(f'The dataset contains {len(df)} observations.')df.head()

neural_prophet_2.py hosted with by GitHub

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

Затем мы выводим данные на график, чтобы иметь возможность сделать некоторый базовые предположения. Учитывая взлеты и падения, я могу предположить, что рост популярности коррелирует с сезонами НФЛ. Пожалуйста, поправьте меня, если я ошибаюсь.

df.plot(x='ds', y='y', title='Log daily page views');
# getting the train/test splittest_length = 365df_train = df.iloc[:-test_length]df_test = df.iloc[-test_length:]

neural_prophet_3.py hosted with by GitHub

Prophet

Как уже упоминалось, Prophet упрощает конечным пользователям получение прогнозов. Мы уложились в 4 строчки кода. Мы можем кратко их рассмотреть. Сначала мы создаем экземпляр модели, используя настройки по умолчанию. Затем мы обучаем модель, используя обучающие данные. Чтобы получить прогнозы, нам нужно создать так называемый future dataframe. Мы указываем количество дней, на которое мы хотим сделать прогноз. По умолчанию метод также включает исторические данные. Таким образом, мы получим подобранные величины (прогнозы с использованием данных из обучающей выборки). Наконец, мы получаем прогнозы и сохраняем их в preds_df_1.

prophet_model = Prophet()prophet_model.fit(df_train)future_df = prophet_model.make_future_dataframe(periods=test_length)preds_df_1 = prophet_model.predict(future_df)

neural_prophet_4.py hosted with by GitHub

Обучив модель, мы сопоставляем прогнозы и фактические наблюдения (только из обучающего набора).

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

В качестве последнего шага мы отражаем на графике извлеченные компоненты. Этот процесс аналогичен стандартной декомпозиции временных рядов.

prophet_model.plot_components(preds_df_1);

Мы можем наблюдать на графике тенденцию на протяжении многих лет вместе с недельной и годовой составляющими.

NeuralProphet

К счастью, API NeuralProphet практически идентичен оригинальному Prophet. Таким образом, уже зная, что мы делали в предыдущем примере, нам будет очень легко применить NeuralProphet к задаче прогнозирования временных рядов.

nprophet_model = NeuralProphet()metrics = nprophet_model.fit(df_train, freq="D")future_df = nprophet_model.make_future_dataframe(df_train,                                                  periods = test_length,                                                  n_historic_predictions=len(df_train))preds_df_2 = nprophet_model.predict(future_df)

neural_prophet_5.py hosted with by GitHub

Естественно, мы используем другой класс для инстанцирования экземпляра модели. Другие отличия заключаются в явном указании частоты данных при обучении модели (исходный Prophet был в первую очередь предназначен для ежедневных данных) и упоминании длины исторической выборки, которую мы хотим включить в future dataframe. Чтобы примеры были как можно более похожими, мы включаем все исторические данные.

Как и раньше, мы строим прогнозы, используя следующую строку.

nprophet_model.plot(preds_df_2);

Затем мы наносим компоненты на график. На момент написания в прогнозах нет доверительных интервалов (как правило, в preds_df_2 гораздо меньше столбцов, чем в preds_df_1, но это, скорее всего, скоро изменится!), но мы можем включить невязки для периода обучения.

nprophet_model.plot_components(preds_df_2, residuals=True);

Мы также можем отразить на графике параметры модели, запустив.

nprophet_model.plot_parameters();

Мы включили сюда только два графика, так как оставшиеся два перекрываются с графиками, полученными с помощью plot_components (еженедельная и годовая сезонность).

Сравнение показателей

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

# prepping the DataFramedf_test['prophet'] = preds_df_1.iloc[-test_length:].loc[:, 'yhat']df_test['neural_prophet'] = preds_df_2.iloc[-test_length:].loc[:, 'yhat1']df_test.set_index('ds', inplace=True)print('MSE comparison ----')print(f"Prophet:\t{mean_squared_error(df_test['y'], preds_df_1.iloc[-test_length:]['yhat']):.4f}")print(f"NeuralProphet:\t{mean_squared_error(df_test['y'], preds_df_2.iloc[-test_length:]['yhat1']):.4f}")df_test.plot(title='Forecast evaluation');

neural_prophet_6.py hosted with by GitHub

Запуск этого кода создаст следующий график.

Хотя может быть трудно однозначно сказать, какие прогнозы ближе к фактическим, расчет MSE ясно показывает победителя NeuralProphet.

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

Выводы

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

Лично я бы не советовал всем отказываться пока от Prophet в пользу NeuralProphet, в основном потому, что библиотека все еще молода и постоянно развивается, что может быть не лучшим фактором для использования в производственной среде. Тем не менее, я однозначно рекомендую следить за ее развитием!

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

Ссылки:


Узнать подробнее о курсе "Machine Learning. Advanced"

Смотреть вебинар Кластеризация временных рядов

Подробнее..

KeyClusterer 2.2 Бесплатная кластеризация поисковых запросов

27.04.2021 10:04:26 | Автор: admin

Всем привет! Представляю вашему вниманию новую версию программы KeyClusterer, предназначенной для группировки семантического ядра методами Hard и Soft.


KeyClusterer 2.2

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


Основные изменения


1. Оптимизирована скорость импорта и кластеризации запросов.


Скорость импорта запросов из CSV-файлов на некоторых проектах выросла до 20 раз. Даже для 100000 запросов импорт теперь занимает менее 3-х минут.


KeyClusterer, скорость импорта запросов

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


KeyClusterer, скорость кластеризации запросов

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


Для метода Soft (порог 4):


Число запросов Время кластеризации
5 000 00:00:02
10 000 00:00:04
50 000 00:00:33
100 000 00:02:24
200 000 00:09:53

Для метода Hard (порог 3):


Число запросов Время кластеризации
5 000 00:00:18
10 000 00:01:21
50 000 00:28:42
100 000 00:01:55
200 000 00:07:49

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


2. Добавлено диалоговое окно импорта данных из CSV.


KeyClusterer, импорт данных из CSV

По вашим просьбам мы добавили форму для облегчения импорта проектов из CSV-файлов, в том числе из программы Key Collector.


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


3. Добавлена возможность отмены последних действий при работе с семантическим ядром.


Как известно, автоматическая кластеризация позволяет сделать лишь 40-60% всей работы по группировке ключевых запросов. И зачастую ручная кластеризация занимает немалое время для качественной проработки и догруппировки семантического ядра.


KeyClusterer, отмена последних действий

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


4. Добавлена возможность вырезки и вставки групп и ключевых запросов.


Теперь, помимо переноса групп и запросов методом Drag & Drop, можно вырезать и вставлять запросы и группы при помощи контекстного меню и комбинаций клавиш Ctrl-X и Ctrl-V. Это является более удобным способом манипуляции группами и запросами на больших семантических ядрах.


KeyClusterer, вырезание и вставка групп и ключевых запросов

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


5. Добавлена возможность использования списка стоп-слов для манипуляции ключевыми запросами.


Было добавлено отдельное окно для хранения стоп-слов и манипуляций ими.


KeyClusterer, использование списка стоп-слов

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


Параметры действий при поиске запросов:


  • Полное вхождение (ищем "я пил молоко", находим "молоко я пил вчера").
  • Частичное соответствие (ищем "ил моло", находим "я пил молоко").
  • Точное соответствие (ищем "я пил молоко", находим "я пил молоко").

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


6. Добавлена подсветка найденных слов и частей слова при фильтрации данных.


KeyClusterer, подсветка найденных слов и частей слова

При фильтрации данных, найденные части слова из первого фильтра теперь выделяются желтым цветом, а из второго зеленым.


7. Добавлена возможность работы со списком прокси.


KeyClusterer, работы со списками прокси

Была добавлена поддержка работы программы через прокси с возможностью проверки списка прокси-серверов на работоспособность.


8. Оптимизирована работа с сайтами-исключениями в интерфейсе основных настроек программы.


KeyClusterer, работа с сайтами-исключениями

Список сайтов исключений теперь редактируется в отдельном окне основных настроек программы.


Прочие изменения


  • Добавлена возможность добавления запросов в текущее семантическое ядро проекта.
  • Добавлена возможность перемещения групп и фраз в любое место в списке.
  • Добавлено автоопределение кодировки импортируемых файлов.
  • Добавлена расширенная форма выбора региона Яндекс.
  • Добавлена возможность экспорта данных из левой панели.
  • При кластеризации запросы без собранных данных помещаются в папку [нераспределенные].
  • Размер шрифта теперь меняется только на панелях с запросами, а не во всем интерфейсе.
  • Добавлено оповещение о выходе новой версии программы.

KeyClusterer, главное окно программы

Пока на этом все.
Будем рады любым замечаниям и предложениям по доработкам и улучшению функционала программы.
Подробнее..

KeyClusterer 2.3 Многопоточность, интеграция с Key Collector

25.05.2021 16:13:10 | Автор: admin

Всем привет! В новой версии KeyClusterer нами была проведена работа над оптимизацией импорта данных, добавлена многопоточность с возможностью сбора данных в поисковой системе Google, добавлено отображение ТОП сайтов по видимости. Ниже детали о новой версии.


KeyClusterer 2.3

Основные изменения


1. Добавлен импорт данных из Key Collector 4.


В новой версии KeyClusterer добавлена возможность импорта данных из программы Key Collector 4-й версии.


KeyClusterer, импорт данных из Key Collector 4

Теперь можно производить импорт запросов, частотностей, позиций, посадочных и SERP напрямую из файлов формата *.kc4, без промежуточного экспорта данных в CSV или Excel.


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


2. Добавлена возможность сбора данных для кластеризации в поисковой системе Google.


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


KeyClusterer, сбор данных в Google

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


  • домен (google.com, google.ru, google.com.ua...)
  • язык (Russian, English, Ukrainian...)
  • страна (Russian Federation, United States, Ukraine...)
  • место ("Moscow,Russia", "New York,United States", "Kyiv city,Ukraine"...)

KeyClusterer, настройки поиска Google

Например, при указании в поисковой системе Google домена "google.com.ua", поисковик будет производить поиск только в украинском сегменте интернета, а при дополнительном указании региона "Kyiv city,Ukraine", будет получать данные с учетом указанного местоположения.


3. Добавлено отображение ТОП сайтов по видимости.


Данный функционал поможет выявить наиболее популярные сайты в вашей тематике (сайты в списке отсортированы по числу запросов, входящих в ТОП-10 по каждому сайту).


KeyClusterer, ТОП сайтов по видимости

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


4. В быстром фильтре добавлена возможность выбора параметров фильтрации.


Таким образом, фильтрацию данных теперь можно осуществить по трем различным параметрам:


  • По кластерам и фразам.
  • По кластерам.
  • По фразам.

KeyClusterer, быстрая фильтрация данных

Это позволит более гибко проводить манипуляции семантическими ядрами больших размеров.


Прочие изменения


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

Будем рады любым замечаниям и предложениям по доработкам и улучшению функционала программы.
Подробнее..

Как автоматизировать сбор и очистку семантики от дублей и мусора

24.06.2020 12:16:00 | Автор: admin
Как автоматизировать сбор и очистку семантики от дублей и мусора

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


На примере интернет-магазина электроники по шагам показываем, как с помощью инструментов Click.ru собрать пул запросов для контекста и привести его в юзабельный вид.


1. Собираем пул запросов


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


Как с ним работать:


1. Зарегистрируйтесь в Click.ru. Кликните Создать аккаунт. В открывшемся окне выберите рекламную систему и назовите аккаунт.


Как автоматизировать сбор и очистку семантики от дублей и мусора

2. Добавьте кампанию. Назовите ее, выберите места показа объявлений, укажите URL, геотаргетинг.


Как автоматизировать сбор и очистку семантики от дублей и мусора

3. Система предложит подобрать слова или добавить свои. Кликните Подобрать слова медиапланер подберет ключевые слова на основе контента рекламируемого сайта.


Как автоматизировать сбор и очистку семантики от дублей и мусора

4. Добавьте подобранные слова в медиаплан. В нашем примере система собрала 623 ключевых слова. Для добавления их в медиаплан установите галочку в шапке таблицы и кликните Добавить в медиаплан.


Как автоматизировать сбор и очистку семантики от дублей и мусора

5. Расширьте семантическое ядро словами, по которым продвигаются ваши конкуренты. Для этого в разделе Автоматический подбор слов выберите Слова конкурентов.


Система предложит до 5 конкурентов и соберет по ним слова. Проверьте, совпадает ли ассортимент предложенных сайтов-конкурентов с вашим. Если нет, удалите предложенные сайты и задайте URL конкурентов самостоятельно (до 10 площадок за раз).


Системе потребуется несколько минут на сбор слов. После этого кликните Показать слова конкурентов.


Как автоматизировать сбор и очистку семантики от дублей и мусора

В примере система собрала 2849 слов. Для их просмотра пролистайте таблицу вниз и нажмите Показать все.


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


  • Удалить их сразу вручную
  • Почистить уже в самом конце после группировки (тогда словам можно будет удалять пачками, а не по одному).

Если слов много, лучше выбрать второй вариант.


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


Как автоматизировать сбор и очистку семантики от дублей и мусора

Выгрузите добавленные в медиаплан слова в XLSфайл.


Как автоматизировать сбор и очистку семантики от дублей и мусора

С помощью двух подборщиков (по контенту сайта и по словам конкурентов) получилось собрать и добавить в медиаплан 3492 слова. Теперь все это нужно очистить.


2. Удаляем дублирующиеся запросы, спецсимволы, пробелы, пустые строки


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


Что он умеет:


  • Удалять дубликаты слов в точном вхождении. Например, если инструмент обнаружит в списке две ключевые фразы купить samsung galaxy s10, то одну из них он удалит.
  • Удалять дубли с учетом морфологии и перестановки слов. Например, если система обнаружит две фразы купить samsung galaxy s10 и samsung galaxy s10 купить, то вторая фраза будет считаться дублем и будет удалена.
  • Удалять спецсимволы в начале и конце слова. В собранных запросах (особенно если это делается с помощью сторонних сервисов) могут попадаться спецсимволы: вопросительные знаки, плюсы и минусы. Например, нормализатор нашел в списке слов фразу с плюсом: samsung galaxy s10 + купить. Он просто удалит плюс и лишние пробелы, а сам запрос останется без изменений.
  • Удаляет лишние пробелы. Если в начале, середине или в конце ключевой фразы есть лишние пробелы, то инструмент обнаружит их и удалит.
  • Удаляет табуляцию и пустые строки. Инструмент удаляет отступы в начале и конце строки. Если в таблице есть пустые строки, то они тоже удаляются.
  • Преобразовывает слова в нижний регистр. Если в списке есть спарсенные заголовки, прописанные в верхнем регистре, то система их переводит в нижний регистр.
  • Заменяет ё на е. Если вы не используете букву ё, то установите галочку напротив опции Заменить ё на е.

Особенности инструмента:


  • Бесплатное использование.
  • Проверка осуществляется онлайн. Не надо устанавливать софт или держать страницу открытой.
  • Неограниченное количество слов в списке.
  • Выполненные задачи хранятся в аккаунте Click.ru неограниченное количество времени.
  • Не надо вводить капчу.

Как использовать инструмент


Перейдите на страницу инструмента и добавьте слова.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Выберите, какие действия необходимо выполнить с ядром, и нажмите Выполнить.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Системе понадобится пара минут, чтобы выполнить заданные действия. Отчет доступен для загрузки в виде XLSX-файла.


Для загрузки отчета в Списке задач нажмите на кнопку Скачать XLSX.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Отчет состоит из двух страниц:


  • очищенный от дублей список слов;
  • исходные настройки (исходный список слов и настройки необходимых действий с ядром).

Фрагмент отчета:


Как автоматизировать сбор и очистку семантики от дублей и мусора

В примере исходный список состоял из 3492 запросов. После чистки их количество сократилось до 2828 слов, то есть дубликаты занимали 19% ядра.


3. Удаляем слова с нулевой частотностью


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


Для проверки частотности большого массива ключей в Click.ru есть парсер Wordstat. Он собирает частотности из левой колонки Wordstat. Он парсит частотность в любом регионе Яндекса и учитывает тип соответствия ключевых слов.


Как пользоваться инструментом


Перейдите на страницу инструмента. Добавьте запросы.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Выберите регион, по которому инструмент будет парсить частотности.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Укажите параметры сбора частотности. Инструмент собирает частотности по запросам в широком соответствии, фиксирует количество слов и морфологию, фиксирует порядок слов.


Как автоматизировать сбор и очистку семантики от дублей и мусора

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


Для запуска задачи нажмите кнопку Запустить проверку. Время сбора зависит от количества запросов, регионов и типов соответствия.


Отчет доступен в списке задач в формате XLSX.


Как автоматизировать сбор и очистку семантики от дублей и мусора

В отчете указывается частотность запросов в разных типах соответствия. Удалите слова с нулевой и околонулевой частотностью.


Важно! Будьте внимательны с ключевыми словами, связанными с сезонными товарами/услугами. В Вордстате статистика собирается за последний месяц, поэтому если сейчас в вашей нише спад, частотность будет низкой. Детально об анализе частотности в Вордстате мы писали здесь. Также вам может помочь сервис Google Trends. Как с ним работать, тоже рассказывали.


После удаления нулевок можно приступать к группировке слов.


4. Разбиваем собранные слова на группы и завершаем очистку ядра


Для группировки ключевиков используйте кластеризатор. Инструмент группирует слова на основе сравнения ТОПов поисковой выдачи в заданном регионе. Инструмент обычно используют SEO-специалисты для разбивки ключей по страницам. Но также он хорошо подходит для целей контекстной рекламы.


Как пользоваться инструментом


Перейдите на страницу инструмента. Для удобства навигации в отчетах укажите адрес сайта и назовите проект.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Загрузите запросы файлом или списком. В списке должно быть не менее 20 запросов.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Выберите способ кластеризации. Доступно два варианта: сравнение ТОПов и профессиональная настройка. В настройках укажите поисковую систему, диапазон точности, количество слов в кластере (для профессиональной настройки). Нажмите на кнопку Запустить кластеризацию.


Как автоматизировать сбор и очистку семантики от дублей и мусора

Подробнее о настройке и возможностях кластеризатора Click.ru читайте в статье Как сгруппировать ключевые запросы с помощью кластеризации?


Скачайте отчет в списке задач.


Как автоматизировать сбор и очистку семантики от дублей и мусора

В отчете запросы для объявлений сгруппированы по кластерам на основе результатов поисковой выдачи. Просмотрите отчет и удалите кластеры с нерелевантными запросами. Это намного удобней делать именно сейчас, а не по одному слову на этапе подбора.


В результате вы получите сгруппированную и очищенную от мусора семантику, готовую к применению.


Не хватает слов для семантики расширьте список


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



Подробно о расширении ядра в узкой нише читайте в статье Как расширить англоязычную семантику для поисковой рекламы в узкой нише.


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

Подробнее..

Модификация EM-алгоритма для решения задачи кластеризации с выбросами

05.06.2021 12:14:00 | Автор: admin

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

Один из подходов к решению данной задачи (чтобы метод кластеризации автоматически отсеивал выбросы) получил название "optimally tuned robust improper maximum likelihood estimator" и был описан вот в этой статье 2017 года (http://dx.doi.org/10.1080/01621459.2015.1100996), а недавно и получил реализацию на R. Поговорим о нем.

Минутка теории

Если совсем вкратце - кластеризация с помощью EM - алгоритмов основана на предположении, что конкретные кластеры имеют форму, близкую к форме многомерного нормального распределения. Тогда задачу кластеризации можно рассматривать как задачу выделения компонентов смеси и кластеры определяются согласно вероятности попадания в тот или иной компонент.

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

 - несобственная постоянная плотность (плотность шума) - несобственная постоянная плотность (плотность шума)

Это приводит к некоторому усложнению решения задачи оптимизации, которая теперь выглядит как решение задачи на максимум

но вот с такими ограничениями

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

Эксперимент

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

library(ggplot2)# Создаем базу данныхset.seed(739)n <- 500 # numer of pointsy <- abs(c(rnorm(n,5,2)))x <- c(rnorm(n,5,1))/sqrt(y)class<-rep(1,n)dat1 <- as.data.frame(cbind(x,y,class)) # Первый кластер - что-то типа кривоугольного прямоугольного треугольникаy <- c(rnorm(n,8,0.4))x <- rlnorm(n, meanlog = log(7), sdlog = 0.2) class<-rep(2,n)dat2 <- as.data.frame(cbind(x,y,class)) # Второй кластер - больше похож на форме на горизонтальный прямоугольникy <- c(runif(n, min = 2, max = 7))x <- c(rnorm(n,8,0.4))class<-rep(3,n)dat3 <- as.data.frame(cbind(x,y,class)) # Третий кластер - вертикальный прямоугольникy <- c(runif(n/10, min = 0, max = 10))x <- c(runif(n/10, min = 0, max = 10))class<-rep(0,n/10)dat4 <- as.data.frame(cbind(x,y,class)) # Шумdat <- rbind(dat1,dat2,dat3,dat4)colnames(dat) <- c("x","y", "class")dat$class <- as.factor(dat$class)dat_test <- as.data.frame(dat)p_base <- ggplot(dat,aes(x=x,y=y,color=class)) + geom_point()ggExtra::ggMarginal(p_base, groupColour = TRUE, groupFill = TRUE)

Получаем вот такую картинку

Здесь и далее меткой "0" обозначаются наблюдения, определенные как шумЗдесь и далее меткой "0" обозначаются наблюдения, определенные как шум

Пакет otrimle достаточно современен в том плане, что в нем уже есть функция, позволяющая сравнить результаты кластеризации в случае задания нескольких кластеров. Зададим число кластеров от 2 до 5, и попробуем посмотреть на ход выполнения.

library(otrimle)clus <- otrimleg(dat[,c(1,2)], G=2:5, monitor=1) # параметр monitor позволяет видеть ход выполнения

В результате выведется вот что-то такое

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

clus$solution

и получаем следующую информацию

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

clus_2 <-otrimle(dat[,c(1,2)], G = 5, npr.max = 0.01, erc = 20, monitor = TRUE)# npr.max - максимальная доля выбросов в выборке# erc - соотношение максимального/минимального собственных значенияclus_2$codeclus_2$flag

Если clus_2$code возвращает 0, это значит, что задача оптимизации вообще не решилась, если clus_2$code = 1, это означает, что EM-алгоритм не сошелся (и надо поиграться с параметрами), если clus_2$code = 2, то все хорошо, алгоритм все посчитал.

Параметр clus_2$flag дает информацию о внутренней структуре работы алгоритма. Если

clus_2$flag = 1, то присутствует вырождение апостерирорных вероятностей

Фактически, это говорит о наличии лишних кластеров, так как вероятность одного из компонент смеси близка к 0.

clus_2$flag = 2, то для сходимости алгоритма было нарушено предположение о доли шума

clus_2$flag = 3, то для при расчетах ограничение на долю шума было использовано

clus_2$flag = 4, то для при расчетах было использовано ограничение на отношение собственных значений

В нашем случае все хорошо (clus_2$code = 2, clus_2$flag = 4), продолжаем разбираться дальше.

clus_2$mean # центра кластеровhead(clus_2$tau) # вероятности принадлежности к кластерамhead(clus_2$cluster) # принадлежность к кластерам

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

Слева - истинное разбиение, справа - предложенное алгоритмом для случая 5 кластеровСлева - истинное разбиение, справа - предложенное алгоритмом для случая 5 кластеровСлева - истинное разбиение, справа - предложенное алгоритмом для случая 4 кластеровСлева - истинное разбиение, справа - предложенное алгоритмом для случая 4 кластеровСлева - истинное разбиение, справа - предложенное алгоритмом для случая 3 кластеровСлева - истинное разбиение, справа - предложенное алгоритмом для случая 3 кластеровСлева - истинное разбиение, справа - предложенное алгоритмом для случая 2 кластеровСлева - истинное разбиение, справа - предложенное алгоритмом для случая 2 кластеров

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

Подробнее..
Категории: R , Кластеризация

Категории

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

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru