Привет, Хабр!Меня зовут Саша и я учусь на втором курсе «Прикладной математики и информатики» в Питерской Вышке. В осеннем семестре я занималась научно-исследовательской работой, в которой сравнивала IT-тенденции. Эта история о том, как я не хотела изобретать велосипед, а в итоге открыла целый велосипедный магазин.  В этом посте я расскажу, как собирала и анализировала данные с Хабра, Хабр Карьеры и Stepik и какие тренды мне удалось нащупать. Возможно, эта информация будет полезна начинающим специалистам, которые только строят свою карьерную траекторию [спойлер: подумайте, точно ли хотите идти в веб-разработку].  Этот проект я выбрала, потому что он показался мне интересным. Я представляла, как сижу, окруженная мониторами, на которых открыто с десяток графиков, а выяснение причин падения тех или иных показателей закручено не хуже, чем в Докторе Хаусе. В общем, работа предполагала сбор статистики и ее анализ, но мой machine learning бэкграунд не давал спать по ночам. Поэтому я решила использовать машинное обучение для обобщения и приведения к единому виду информации, полученной из разных источников.  Для начала хочу рассказать, что именно я исследовала. Под тенденцией я понимаю поведение временного ряда в течение некоторого периода, где в качестве параметров выступают, например, количество выпущенных статей на какую-то тематику в определенный момент времени. Чтобы определить популярность разных IT-направлений, я решила исследовать три области: рынок труда, образовательные курсы и тематические блоги. В каждой из областей выбрала по одному ресурсу: для получения информации о вакансиях – career.habr,  для курсов – Stepik. И где можно взять кучу статей на программистские тематики, если не на Хабре? Поэтому основным ресурсом с профессиональными статьями стал именно он.  Сначала ничего не предвещало беды: что может быть проще, чем написать небольшой парсер, добыть кучу интересных данных и начать рисовать картину происходящего с прикольными графиками и умным видом? Проблема заключалась в том, что на каждом ресурсе информация лежит в своем пузыре: на Хабре это будут теги или хабы, у вакансий – ключевые навыки и требования, у курсов – тематики. Соотносить их вручную долго, а мне хотелось получить общую картину и провести сравнительный анализ сразу на всех площадках. Тут-то я и начала прикручивать колеса своему велосипеду, а именно стала разрабатывать план по захвату мира получения нужной мне информации. Если кратко, то его можно изложить в трех пунктах: Сбор данных: набор статей, курсов и вакансий. Кластеризация хабов Хабра для определения основных направлений, тенденции в которых в итоге и нужно будет исследовать. Категоризация неразмеченных данных, т.е. нужно соотнести курсы и вакансии с направлениями, которые у меня получились на предыдущем шаге. Для парсинга я выбрала фреймворк Scrapy. Для каждого из сайтов: Хабр, Хабр Карьера и Stepik – написала пауки, которые просто «стягивали» текстовые данные прямо мне в табличку. Всего удалось добыть около 100 тысяч статей, 20 тысяч вакансий и 1.5 тысячи курсов. Помимо основной информации вроде тегов, ключевых навыков и названий курсов, мне пригодилась информация, отражающая заинтересованность людей: количество комментариев, участников и т. д.  В сыром виде данные мне были не нужны, поэтому пришлось их пожарить лемматизировать и все тексты разбить на токены.  Вообще, хабы Хабра уже являются своего рода кластерами. Однако их было слишком много, чтобы размечать ими другие данные, поэтому я решила кластеризовать их еще раз, но уже для своих целей. Векторное представление хабов было сделано с помощью библиотеки word2vec, а для размерности вектора я выбрала число 100 (ну, потому что красивое). В результате обучения модели на 100 тысячах статей, хабы разбились на 11 основных направлений:  машинное обучение (ну еще бы);  железо, электроника; сетевые технологии, администрирование, devops; проектирование, тестирование; информационная безопасность; маркетинг, контекстная реклама; верстка, html, javascript; e-commerce, финансы; дизайн интерфейсов; бизнес, CRM; SEO. Число 11 было выбрано с помощью метода колена локтя, а чтобы модель кластеризации обучалась быстрее, размерность была снижена с помощью PCA.  Для кластеризации я использовала модель Agglomerative Clustering из библиотеки sklearn. Зачем? Потому что картинка красивая. Для выбора наиболее подходящего метода пришлось снижать размерность векторов до 2-х измерений, чтобы можно было примерно представить, как они выглядят на графике: На точечной диаграмме, очевидно, больше 11 кластеров. Но не нужно забывать, что кластеризировались векторы большей размерности. Существующие 100-мерные вектора обладали слишком большой размерностью для обучения (и для моего бедного ноутбука), поэтому я выбрала число измерений, которые покрывают 90% выборочной дисперсии данных. В итоге получились 8-мерные вектора. После выделения кластеров их нужно было как-то назвать. Названия я выбирала исходя из близости конкретного хаба к центроиду кластера и его популярности.  Здесь история заходит в ту ветвь, где мне приходится объяснять, почему одного велосипеда стало недостаточно, и пришлось открыть небольшую лавку по продаже велосипедных ортопедических сидений. После получения кластеров передо мной встала задача соотнести каждую вакансию и курс с одним или несколькими направлениями – классическая мультиклассовая задача категоризации. Казалось бы, уже изобретено множество эффективных подходов к категоризации текстовых данных, ну хотя бы нейронные сети LSTM, GRU. Однако к тому моменту, когда я дошла до этой задачи, я не обладала черным поясом в искусстве построения нейронных сетей, поэтому пришлось использовать прежний подход – векторизовать имеющиеся текстовые данные с помощью уже обученной модели word2vec и строить несложную полносвязную нейронную сеть с несколькими слоями, где выходными нейронами как раз и были те 11 направлений.  Этот подход сработал: метрика multi-accuracy на тестовых данных составила 94% (тестовыми и тренировочными данными все так же служили статьи Хабра, так как после кластеризации хабов разметить их было несложно). В этой задаче не нужно было применять рекуррентные нейронные сети (чаще всего именно они используются для работы с текстом): в обучающие данные входили наборы тегов, хабов и каких-то ключевых слов, поэтому они не были связаны между собой, как если бы стояли в одном предложении. Поэтому последовательность слов вовсе не являлась последовательностью, а была, скорее, набором признаков. Как я уже рассказывала, каждое слово представлялось в виде 100-мерного вектора, а чтобы получить результирующий вектор, который и будет скормлен нейронной сети, все вектора из одного набора я складывала. Это имеет смысл, так как модель word2vec позволяет получить именно семантическое представление слова в векторном виде. Поэтому если сложить слова data и science, мы вполне получим что-то близкое к машинному обучению. Саму нейронную сеть я написала на фреймворке PyTorch (еще до того, как поняла, что Keras для меня в разы удобнее). Разметить курсы Stepik оказалось не так просто. После визуальной оценки предсказаний модели я пришла к выводу, что здесь она справилась плохо. Только около 200 курсов из 1,5 тысяч были размечены верно, поэтому мне пришлось вернуться к предкам, а именно добыче огня разметке данных вручную. В какой-то момент мне надоело (ведь не так я представляла жизнь программиста!), поэтому разметив треть данных, я обучила на них уже написанную мною нейронную сеть, а для оставшихся – получила предсказания. В итоге для анализа у меня были готовы тысячи наблюдений с разных площадок в период с 2016 по 2021 годы. Для всех наборов данных по каждому направлению я построила линии тренда, а помимо количества наблюдений я также исследовала взаимодействие людей с данными сферами, то есть, например, количество комментариев и просмотров. Стоит отметить, что я рассматривала именно процентные соотношения, а не абсолютные величины – так можно избежать влияния набирающей популярности какой-то площадки из трех выбранных. Помимо этого, с сайта career.habr удалось собрать интересную статистику по наиболее популярным профессиям и проанализировать тенденции по ним.  Пожалуй, я не буду подробно рассказывать о трендах по всем выделенным направлениям. Остановлюсь только на «технических» (а об остальных, если вам интересно, могу рассказать в комментариях). Наиболее сильный рост наблюдается у направления «Железо и электроника»: количество вакансий стабильно растет, как и заинтересованность людей: Несколько печальнее ситуация обстоит с веб-разработкой: количество вакансий и статей снижается, а активность пользователей (комментарии, сохранения, просмотры) растет: Это также заметно и при анализе спроса на Frontend-разработчиков и PHP-разработчиков – количество вакансий падает: Обратная ситуация с машинным обучением: спрос на рынке труда и в образовательной сфере набирает обороты (хоть и не настолько значительно), в то время как активность пользователей на данную тему начинает угасать: Тот же самый вывод можно сделать и об администрировании и Devops: это направление становится все более популярным у работодателей, хоть и интерес людей немного снижается: Похожая ситуация с информационной безопасностью: интерес работодателей в данной сфере растет, что и отражается в повышающемся спросе на курсы, однако среди блогов популярность данной темы сильно снижается. Несмотря на уменьшающееся количество статей по направлению проектирование и тестирование, в целом интерес как со стороны читателей блогов и участников курсов, так и со стороны рынка труда, немного возрастает.  Можно долго рассуждать, почему получились те или иные результаты. Но, как мне кажется, это достойно отдельного исследования. А что думаете вы? Другие проекты наших студентов: Как найти плагиат в контестах по программированию Градиенты в нейронных сетях для поиска аномалий в данных Приложение для аудиозвонков с регулировкой звука, как в реальной жизни Питерская Вышка