Исследование рынка вакансий BA/SA / Хабр

Исследование рынка вакансий BA/SA

«Исследование рынка вакансий аналитиков» — так звучала вполне реальная задача одного вполне реального ведущего аналитика одной ни большой, ни маленькой фирмы. Рисерчер парсил десятки описаний вакансий с hh вручную, раскидывая их по запрашиваемым скиллам и увеличивая счетчик в соответствующей колонке спредшита.

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

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

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

Спойлер: легко и просто не получилось.

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

Если мы хотим собрать кучу данных о вакансиях, то логично hh не ограничиваться. Однако, для чистоты эксперимента простоты начнем с этого ресурса.

Для сбора данных воспользуемся поиском по вакансиям через hh API.

Искать буду с помощью простого текстового запроса «systems analyst», «business analyst» и «product owner», потому как активности и зоны ответственности у этих позиций, как правило, пересекаются.

Для этого нужно сформировать запрос вида https://api.hh.ru/vacancies?text=»systems+analyst» и распарсить полученный JSON.

Чтобы в выборку попали максимально релевантные вакансии, искать будем только в заголовках вакансий, добавив в запрос параметр search_field=name .

Здесь можно посмотреть, какие поля вакансий возвращаются по этому запросу. Я выбрала следующие:

  • название вакансии
  • город
  • дата публикации
  • зарплата — верхняя и нижняя границы
  • валюта, в которой указана зарплата
  • gross — T/F
  • компания
  • обязанности
  • требования к кандидату

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

В функции hh.getjobs() на вход принимается вектор интересующих нас поисковых запросов и уточнение, интересуют нас только вакансии с указанной зарплатой или все подряд (по умолчанию берем второй вариант). Создается пустая dafa frame, а затем используется функция fromJSON() пакета jsonlite , которая принимает на вход URL и возвращает структурированный list. Далее из узлов этого списка мы достаем интересующие нас данные и заполняем соответствующие поля data frame.

По умолчанию данные отдаются постранично, по 20 элементов на каждой странице. Максимально по одному запросу можно получить 2000 вакансий. Все полученные данные мы записываем в df .

Лайфхак 1: совершенно не факт, что по нашему запросу найдется 2000 вакансий, и начиная с какого-то момента нам будут приходить пустые страницы. В этом случае R ругается и выпрыгивает из цикла. Поэтому содержимое внутреннего цикла заботливо обернем в try() .

Лайфхак 2: во внутренний цикл также имеет смысл добавить вывод в консоль текущего статуса сбора данных, потому как дело это небыстрое. Я сделала так:

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

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

Теперь из полного описания вакансий вытащим experience и key_skills .

Функции hh.getxp передаем data frame, проходимся по сохраненным ссылкам на вакансии, и из полного описания достаем значение требуемого опыта работы. Полученное значение сохраняем в новом столбце.

Описание новой вспомогательной функции отправляется в functions.R , а основной скрипт теперь обращается к ней:

В фрагменте выше мы также формируем новую data frame all.skills вида «id вакансии — навык»:

Препроцессинг

Посмотрим, сколько всего данных удалось собрать:

Почти полторы тысячи вакансий! Выглядит неплохо. И по всей видимости, несколько вакансий попались в результатах поиска дважды — по разным запросам. Поэтому первым делом оставим только уникальные записи: jobdf .

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

1) убедиться, что все имеющиеся данные по зарплатам представлены в единой валюте,

2) выделить в отдельную data frame те вакансии, для которых зарплата указана.

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

Чтобы перевести значения зарплат в рублевые, нужно узнать актуальный курс валют. Узнавать будем у Центробанка:

Чтобы курсы корректно обрабатывались в R, нужно убедиться, что десятичная часть отделена точкой. Кроме того, стоит обратить внимание на колонку Nominal: где-то он равен 1, где-то 10 или 100. Это значит, один фунт стерлингов стоит

85 рублей, а, скажем, за сотню армянских драмов можно купить

13 рублей. Для удобства дальнейшей обработки я привела значения к номиналу 1 относительно рубля.

Теперь можно и переводить. Наш скрипт делает это с помощью функции convert.currency() . Актуальный курс валют в ней берется из таблицы quotations , куда мы сохранили данные из XML, предоставляемой Центробанком. Также на вход функция принимает целевую валюту для конвертации (по умолчанию RUR) и таблицу с вакансиями, значения зарплатных вилок в которой необходимо привести к единой валюте. Функция возвращает таблицу с обновленными зарплатными цифрами (уже без столбца Currency, за ненадобностью).

Вам будет интересно  Доллар торгуется у минимума почти за 2,5 года после встречи ФРС США

С белорусскими рублями пришлось повозиться: после получения весьма странных данных в несколько подходов, я провела небольшой рисерч и узнала, что начиная с 2016 года в Беларуси используется новая валюта, которая отличается не только курсом, но и аббревиатурой (теперь не BYR, а BYN). В справочниках hh до сих пор используется аббревиатура BYR, про которую XML от Центробанка ничего не знает. Поэтому в функции convert.currency() я не самым изящным образом сначала заменяю аббревиатуру на актуальную, и только затем перехожу непосредственно к конвертации.

Выглядит все это следующим образом:

Также можно учесть, что некоторые данные по зарплатам представлены в значениях gross, то есть на руки сотрудник будет получать несколько меньше. Чтобы рассчитать зарплату net для резидентов РФ, нужно вычесть из указанных цифр 13% (для нерезидентов вычитается 30%).

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

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

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

Анализ

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

  • средний уровень зарплат BA/SA,
  • наиболее востребованные умения и личные качества на этой позиции,
  • зависимости (если есть) между определенными навыками и уровнем зп.

Средний доход BA/SA

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

В нашей data frame jobdf эти значения находятся в колонках To и From соответсвенно. Я хочу найти средние значения и записать их в новый столбец Salary.

Для кейсов, где зарплата указана полностью, это легко сделать с помощью функции mean() , отфильтровав все остальные записи, где данные по вилке отсутствуют полностью или частично. Но в этом случае от нашей исходной выборки, которая и так невелика, осталось бы менее 10%. Поэтому я вычисляю коэффициент Подгониана , который подсказывает, насколько в среднем отличаются значения To и From в вакансиях, где указана полная вилка, и с его помощью примерно заполняю недостающие данные в кейсах, где пропущенно только одно значение.

Это «мягкая» фильтрация данных, которая в функции select.paid() задается параметром suggest = TRUE . Альтернативно мы можем указать suggest = FALSE при вызове функции и просто выпилить все строки, где зарплатные данные хотя бы частично отсутствуют. Однако с использованием мягкой фильтрации и волшебнго коэффициента мне удалось сохранить в выборке почти четверть от исходного набора данных.

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

На этом графике можно визуально оценить плотность распределения зарплат BA/SA в двух столицах и в регионах. Но что если конкретизировать запрос и сравнить, сколько получают миддлы и сеньоры в столицах?

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

120 т.р., а разница в доходах старших специалистов уровня в Москве и Санкт-Петербурге отличается в среднем на 60 тысяч.

Также мы можем взглянуть, например, на московские зарплаты аналитиков в разрезе должности:

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

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

Полный код для графиков под катом.

Анализ навыков (Key skills)

Переходим к ключевой цели исследования — определить наиболее востребованные навыки для BA/SA. Для этого проведем анализ тех данных, что в явном виде указаны в специальном поле вакансии — key skills.

Наиболее популярные навыки

Ранее мы получили отдельную data frame all.skills , куда записали пары «id вакансии — навык». Найти наиболее часто встречающиеся скиллы несложно с помощью функции table() :

Получится примерно следующее:

Здесь Freq — это количество вакансий, в поле «key_skills» которых указан соответствующий навык из столбца Skill.

Вам будет интересно  Надежные инвестиционные проекты в интернете

«Но это еще не все!»(ц) Совершенно очевидно, что одни и те же скиллы запросто могут встречаться в разных вакансиях в синонимичных выражениях.

Я составила небольшой словарь синонимов названий скиллов и разделила их по категориям.

Словарь представляет собой csv-файл со столбцами category — одно из следующего: Activities, Tools, Knowledge, Standards и Personal; skill — основное название навыка, которое я буду использовать вместо всех найденных синонимов; syn1, syn2,… syn13 — собственно возможные вариации для каждого навыка. Некоторые строки могут содержать пустые столбцы синонимов.

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

Под катом можно посмотреть начинку функции categorize.skills() .

Я добавляю к исходной data frame с навыками столбец category и skill. group — для категории и обобщающего названия навыка соответсвенно. Затем я прохожусь по импортированному словарю и из каждой строчки синонимов составляю паттерн для функции grep() . Добавляя каждое непустое значение колонки к строке, я разделяю их чертой, чтобы получить условие «или». Так, для всех скиллов из исходной таблицы, в которые входит паттерн uml|activity diagram|use case diagram|ucd|class diagram , я запишу в колонку skill.group значение «uml». И так будет с каждым. скиллом из исходной data frame.

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

В тройке лидеров теперь управление проектами, бизнес-анализ и документирование, а знание UML сместили из топ-7.

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

Например, для категории Knowledge дело обстоит следующим образом:

Из графика видно, что наибольшим спросом пользуются знания в области баз данных, методологий разработки ПО и 1С. Далее идут знания в области CRM, ERP-систем и основы программирования.

В том, что касается стандартов, действительно большим спросом пользуется знание SQL и UML, на пятки им наступает нотация ARIS, а вот ГОСТы занимают всего лишь шестое место.

Что касается используемых тулов, — мы лишний раз видим подтверждение тому, что основным инструментом аналитика является голова. Без линейки MS Office и таск-трекинговых систем не обойтись, а в остальном мало кого волнует, в каком именно редакторе аналитик создает свои схемы или набрасывает макеты интерфейсов.

Влияние навыков на доход

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

Для начала соединим интересующие нас столбцы из таблиц по вакансиям jobs.paid и скиллам all.skills , чтобы было удобнее строить графики на основе полученной data frame.

Получится таблица следующего вида:

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

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

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

Что касается используемых инструментов, начиная от пакета MS Office и заканчивая софтом для составления диаграмм и создания мокапов, — здесь данных оказалось слишком мало, чтобы на их основании делать какие-то выводы о связи между владением определенным инструментом и уровнем дохода. Более того, чем выше зарплата, обозначенная в вакансии, тем меньше внимания уделяется конкретным инструментам в арсенале аналитика.

В том, что касается стандартов, картина немного отличается: умение обращатсья с нотациями UML и ARIS, а также знания SQL стабильно востребованы (в своих пропорциях) при разных уровнях зарплат, а вот знание IDEF — уже не такой популярный запрос, который и вовсе отсутствует на «максималках».

Анализ текста вакансий

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

Импорт и подготовка описаний

Посмотрим, как выглядит типичное описание вакансии в нашей исходной data frame:

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

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

Это, впрочем, не является обязательнм шагом, поскольку сравнивать тексты вакансий я собираюсь все с тем же словарем, составленным вручную. Следующая функция принимает на вход data frame и словарь (также в виде df), пробегается по столбцу с полным описанием вакансии, ищет совпадения со словарем и формирует новую df вида «id, skill.group, category».

Вам будет интересно  Белорусский агростартап OneSoil привлек $5 млн и набирает украинских специалистов

Снова о самых востребованных навыках

Проверим, что получается?

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

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

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

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

И снова о деньгах

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

Для построения графиков сформируем новую data frame из перечня скиллов, полученных из описания вакансий, и таблицы вакансий с указанными зарплатами. При этом сразу оставим только те записи, которые относятся к Москве и Санкт-Петербургу.

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

Что мы видим из этого графика?

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

Во-вторых, несмотря на это, наиболее «денежными» занятиями является непосредственно бизнес-анализ, создание макетов интерфейсов и проведение исследований.

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

Глядя на график, можно сделать вывод, что на самом деле в зарплатном сегменте свыше 150 т.р. есть необходимость в специалистах со знанием не только UML или ARIS, но и IDEF, и ГОСТов, однако спрос на знание ГОСТов заметно ниже — в этой части первоначальный вывод подтверждается.

Некоторые изменения наблюдаются и в области личностных качеств аналитика:

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

А как же бесценный опыт?

Например, вот так выглядит плотность распределения зарплат в Москве для специалистов-аналитиков с различным стажем:

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

Для сравнения, в Санкт-Петербурге разделение куда более выраженное:

Кое-какие выводы

Проведенный анализ ключевых навыков и текстов вакансий BA/SA показал, что

  • качество такого анализа во многом зависит от словаря категорий навыков. В процессе работы я несколько раз обновляла и дополняла таблицу навыков и инструментов, но и сейчас классификация неидеальна;
  • потолок зарплаты аналитика в Москве (и в целом в России) составляет приблизительно 200 т.р. Все, что выше этой цифры, встречается весьма эпизодически и требует нетипичных скиллов вроде знания статистики или специфической предметной области;
  • на рынке вакансий довольно размытая граница между миддлами и сеньорами;
  • главный инструмент аналитика — по-прежнеу голова (выбор тулов, как правило, остается на усмотрение аналитика и не влияет на доход)
  • поле key_skills в вакансиях на hh заполняется через раз, и на основе только него нельзя делать выводы о наиболее востребованных навыках аналитика;
  • анализ текста вакансий, в свою очередь, оказался достовернее и полезнее, поскольку данных в результате парсинга описаний было собрано в пять(!) раз больше;
  • чтобы прийти к успеху во всех отношениях, аналитику стоит наиболее активно прокачивать навык бизнес-анализа, создания добротного UX и английский язык;
  • нельзя недооценивать коммуникативные навыки. Впрочем, их значимость снижается где-то после отметки в 150 т.р.;
  • в том, что касается стандартов, заслуживает упоминания SQL, а также нотации UML & ARIS. Для меня видеть такую популярность языка запросов довольно неожиданно, т.к. за несколько лет мне не приходилось активно его использовать. И это, пожалуй, единственный вывод данного исследования, который противоречит здравому смыслу личному опыту.
Яндекс.Метрика