В чёрную пятницу, пока у нас стартует флагманский курс Data Science, делимся интерактивными графами подписок веб-разработчиков и разработчиков моделей ML, а также знакомим читателей с инструментом визуализации больших графов — PyGraphistry.

Такие данные — косвенный индикатор конкуренции языков и технологий. К примеру, можно попробовать выяснить, сколько разработчиков C++ следят за разработчиками Rust и наоборот. За подробностями и кодом приглашаем под кат.


Интерактивный граф вы найдёте здесь.

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

Мы проанализируем GitHub при помощи набора данных в Kaggle. Узлы — это разработчики, которые поставили звезду не менее чем 10 репозиториям. Если человек является разработчиком машинного обучения, то ml_target=1, иначе ml_target=0.

import pandas as pd

# Download the data at https://www.kaggle.com/femikj/github-social-network
nodes = pd.read_csv("github-social-network/github_target_1.csv")

# Change datatypes
nodes.id = nodes.id.astype(str)
nodes.ml_target = nodes.ml_target.astype(str)

nodes.head(10)

Рёбра (edges) — это наблюдения двух разработчиков друг за другом.

edges = pd.read_csv("github-social-network/github_edges_1.csv")

# Change datatypes
edges = edges.astype(str)

edges.head(10)

Cвязи ML и веб-разработчиков

Доля ML-разработчиков и веб-разработчиков

Начнём с определения процентного соотношения веб-разработчиков — ????(Web Developer) и разработчиков машинного обучения — ????(ML Developer) в сети.

import plotly.express as px

percent_web, percent_ml = nodes.ml_target.value_counts(normalize=True)
px.histogram(data_frame=nodes, x="ml_target", histnorm="probability density")

74% разработчиков в этой сети — веб-разработчики.

Процент смешанных соединений

Каков процент смешанных соединений (между веб-разработчиком и разработчиком машинного обучения)?

Объединим таблицы edges и nodes:

edges = edges.merge(nodes, how="left", left_on="id_1", right_on="id").merge(
 nodes, how="left", left_on="id_2", right_on="id", suffixes=("1", "2")
)[["id_1", "id_2", "name1", "name2", "ml_target1", "ml_target2"]]

edges.head(10)

Затем рассчитайте процент смешанных связей в сети — ????(ML Developer connect to Web Developer).

cross_edge = edges.query("ml_target1 != ml_target2")
percentage_cross_edge = cross_edge.shape[0] / edges.shape[0]
percentage_cross_edge
0.1546558340224842

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

Связи веб-разработчиков

Ещё один интересный вопрос: если человек — веб-разработчик, какой процент его связей — веб-разработчики, а какой — разработчики ML?

Чтобы ответить на этот вопрос, воспользуемся теоремой Байеса. Из этой теоремы известно, что:

Мы уже знаем ????(ML-Developer connect to web Developer) и ????(Web Developer) из предыдущих расчётов. Воспользуемся этими цифрами, чтобы найти ????(connect to ML Developer|Web Developer):

percentage_cross_edge / percent_web
0.20852347708049263

Теперь легко найти ????(Web Developer|Web Developer):

Это означает, что если человек является веб-разработчиком, то:

  • вероятность, что связанные с ним люди тоже веб-разработчики, составляет 71,95%;

  • вероятность, что он связан с разработчиком ML, составляет 28,05%.

Эти цифры очень похожи на процент разработчиков ML и веб-разработчиков в сети (0,258 и 0,741).

Связи разработчиков ML

Мы можем найти ????(Connect to a Web developer|ML Developer):

percentage_cross_edge / percent_ml
0.5986779897985065

И ????(ML Developer|ML Developer):

1 - 0.5897
0.4103

Если человек — разработчик ML, то:

  • вероятность, что связанные с ним или с ней люди также являются веб-разработчиками, составляет 59,87%;

  • вероятность, что связанные с ним люди — разработчики ML, составляет 41,03%.

Поскольку процент разработчиков ML в сети составляет всего 25,8%, удивительно наблюдать, что 41,03% связей разработчика ML — это разработчики ML. То есть разработчики ML с большей вероятностью будут следить друг за другом, чем за веб-разработчиками.

Визуализация сети с помощью PyGraphistry

Давайте попробуем подтвердить этот вывод. Визуализируем сеть GitHub с помощью PyGraphistry.

Что такое PyGraphistry?

PyGraphistry — это библиотека Python для визуализации больших графов. Здесь мы будем работать с большим графом, поэтому PyGraphistry — идеальный инструмент.Чтобы установить его, выполните:

pip install pygraphistry

Начнём

Чтобы использовать PyGraphistry, создайте бесплатный аккаунт graphistry.com:

import graphistry

PASSWORD ="GRAPHISTRY_PASSWORD" # Insert your password here
USERNAME = "GRAPHISTRY_USERNAME" # Insert your username here

graphistry.register(api=3, username=USERNAME, password=PASSWORD)

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

g = graphistry.edges(edges, "id_1", "id_2")

# Choose icons here: https://fontawesome.com/v4.7.0/icons/
g = (g.nodes(nodes, "id").encode_point_icon(
 "ml_target", categorical_mapping={1: "area-chart", 0: "mouse-pointer"}
)

Теперь выводим граф Github:

g.plot()

В вашем блокноте должно появиться что-то вроде этого:

Интерактивный граф вы найдёте здесь.

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

Интерактивный граф вы найдёте здесь.

Щёлкнув по узлу, вы получите информацию о нём.

Цветовое кодирование точек

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

g2 = g.encode_point_color("ml_target", categorical_mapping={1: "silver", 0: "maroon"})
g2.plot()

Интерактивный граф вы найдёте здесь.

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

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

Разработчики с наибольшим количеством связей

Нажмём на значок "Data Table" в верхней части экрана. Отсортируем её по количеству взаимосвязей и щёлкнем по интересующей точке, которая будет выделена:

Интерактивный граф здесь.

Из таблицы видно, что большинство популярных разработчиков — это веб-разработчики. Что неудивительно, ведь веб-разработчиков гораздо больше.

Найдём сообщества

Сообщество — это подмножество узлов, которые в одном и том же графе плотно связаны друг с другом и слабо связаны с узлами других сообществ. Попробуем найти сообщества с помощью метода Лувена. Мы имеем дело с большим графом, поэтому для ускорения кода воспользуемся cuGraph.

import cudf
import cugraph
from cugraph.community.louvain import louvain

# Turn a pandas DataFrame into a graph
G = cugraph.from_pandas_edgelist(edges, "id_1", "id_2")

# Get communities
parts, modularity_score = cugraph.louvain(G)

# View the first 10 rows
parts.head(10)

В таблице ниже, partition — это сообщество, которому принадлежит узел (вершина). Сколько существует сообществ? Давайте узнаем:

parts.partition.unique().values
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], dtype=int32)

Их всего 22. Давайте представим, как выглядят эти сообщества. Объединим таблицы nodes с таблицами parts, чтобы получить имена узлов и их разделов.

# Join the parts and nodes table to get the name of the nodes
nodes_cudf = cudf.from_pandas(nodes)
nodes_part = nodes_cudf.merge(parts, how="left", left_on="id", right_on="vertex")
nodes_part.head(10)

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

from faker import Faker

Faker.seed(0)
fake = Faker()

g3 = (
 g.nodes(nodes_part, "id")
 .encode_point_icon(
 "ml_target", categorical_mapping={1: "area-chart", 0: "mouse-pointer"}
 )
 .encode_point_color(
 "partition", categorical_mapping={i: fake.color() for i in range(22)}
 )
)

g3.plot()

Вы должны увидеть нечто подобное:

Интерактивная версия здесь.

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

Сообщества разработчиков ML и веб-разработчиков

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

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

Кажется, что веб-разработчики принадлежат к самым разным сообществам. А теперь посмотрим, к каким сообществам принадлежат разработчики моделей ML:

Граф только из разработчиков ML:

Интересно! Большинство разработчиков ML принадлежат к сообществу, окрашенному в розовый цвет. Это означает, что, в отличие от веб-разработчиков, разработчики ML, как правило, находятся в одном сообществе. Другими словами, разработчики ML теснее связаны друг с другом.

Процент разработчиков ML в каждом сообществе

Каков процент разработчиков ML в каждом сообществе? Чтобы выяснить это, воспользуемся сгруппированной гистограммой.

from faker import Faker

Faker.seed(0)
fake = Faker()

g3 = (
 g.nodes(nodes_part, "id")
 .encode_point_icon(
 "ml_target", categorical_mapping={1: "area-chart", 0: "mouse-pointer"}
 )
 .encode_point_color(
 "partition", categorical_mapping={i: fake.color() for i in range(22)}
 )
)

g3.plot()

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

Заключение

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

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

Подробности здесь.

Профессии и курсы

Комментарии (1)


  1. mentin
    27.11.2021 01:24

    Мне одному кажется, что с применением Баеса у них что-то не так?

    Начинаем с формулы:

    ????(connect to ML Developer|Web Developer) = percentage_cross_edge / percent_web

    У них эта вероятность могла бы просто напросто оказаться больше единицы, если (в теоретическом эксперименте) все связи между ML и Web, то есть percentage_cross_edge = 1.

    Ну и кроме того, они считают всё по одной цифре percentage_cross_edge, которая не полностью описывает ситуацию - может быть ассимметрия. Скажем (в другом теоретическом эксперименте) ML девелоперы связаны и друг с другом, и с Web, а Web друг-друга игнорируют. Тогда рассчитываемая ими "если человек является веб-разработчиком, вероятность, что связанные с ним люди тоже веб-разработчики" была бы ровно нулём, несмотря на то что percentage_cross_edge могла быть такой же.