Время прочтения: 3 мин.
Рассмотрим пример обнаружения мошенничества.
У нас есть база данных клиентов, и мы хотим знать, как они связаны друг с другом. Мы знаем, что некоторые клиенты участвуют в сложной структуре мошенничества и если мы будем рассматривать таких клиентов индивидуально, то можем не увидеть признаков, доказывающих факт мошенничества. Такие мошенники могут быть похожи на обычных клиентов.
Работа со связями между пользователями может быть более информативна, чем анализ каждого клиента в отдельности. Например, некоторые признаки не считаются рискованными для обычной оценки (номер телефона, адрес электронной почты, домашний адрес), но могут стать критичными при анализе на основе графа.
Приведём пример: четыре человека с повторяющимися номерами телефонов. Некоторые из них связаны с другими клиентами по одному адресу электронной почты. Как мы понимаем, номер телефона сам по себе даёт мало информации если использовать классические методы анализа, но при анализе с помощью графов мы видим, что люди связаны между собой через одни и те же значения телефонных номеров или значения адресов электронной почты, и это может нести риски.
ID | Name | Phone number | |
1 | Степан Иванов | +111 12 34 56 78 | феликс@gmail.com |
2 | Евгений Демьянов | +111 00 00 00 00 | дюран@gmail.com |
3 | Иван Кузнецов | +111 12 34 56 78 | кастом@gmail.com |
4 | Юлия Попова | +123 99 99 99 99 | Null |
5 | Светлана Брилова | +123 0123 4567 | кастом@gmail.com |
6 | Кирилл Устинин | +123 0123 4567 | Null |
Для построения графа мы настроим связи между клиентами по номеру телефона:
ID | ID_2 | Phone number |
1 | 3 | +111 12 34 56 78 |
5 | 6 | +123 0123 4567 |
И по электронной почте:
ID | ID_2 | |
3 | 5 | кастом@gmail.com |
Теперь построим граф с помощью простейшей функции nx.draw (G):
%matplotlib inline
nx.draw(G)
Простой граф отражает связи в общем смысле. Для наибольшей информативность мы добавим разные типы ссылок между клиентами и подписи самих клиентов:
def draw(f):
stnd = nx.spring_layout(f, scale=0.5)
nod_lab = dict((m,h['Name']) for m,h in f.nodes(data=True))
nx.draw(f, pos=stnd, width=e_sizes(f), edge_color=e_colors(f), alpha=0.8, arrows=True, node_color='lightgrey', node_size=400,labels=nod_lab, font_color='black', font_size=8, font_weight='bold')
labels_e = dict(((b,d),list(e.values())[0]) for b,d,e in G.edges(data=True))
nx.draw_networkx_edge_labels(G, stnd, edge_labels = labels_e, font_size=8)
Пример графа с большим количеством вершин с применением созданной функции визуализации: Draw(G)
Как мы видим, представление всего графа при большом количестве вершин может быть не всегда удобным для анализа. В этом случае рекомендуется выделять подграфы с помощью функции ego_graph. На вход в n подается ID ноды (клиент) от которого исследуется связь и в radius – расстояние в нодах от n:
Draw(nx.ego_graph(G=G, n=int(df1[df1['Name'] == 'Степан Иванов'].ID), radius=3))
Благодаря нашей дополнительной функции мы видим какие клиенты связаны и по каким признакам связаны друг с другом.
В нашем случае интересны не клиенты сами по себе, а то как они связаны друг с другом. Визуализация при помощи графа помогает нам с этой задачей.