图形分析不是数据科学的新分支,但并不是科学家今天应用的常用“首选”方法。然而,图表可以做一些疯狂的事情。经典用例包括欺诈检测,推荐,社交网络分析。NLP中的非经典用例处理主题提取。

可视化的 graph-of-words,其中每个社区代表不同的主题
考虑欺诈检测用例
您有一个客户数据库,并想知道它们是如何相互连接的。特别是,您知道有些客户涉及复杂的欺诈结构,但是在个人层面上可视化数据并不会带来欺诈证据。欺诈者看起来像其他普通客户。
只需查看原始数据,处理用户之间的连接就可以显示更多信息。具体而言,对于基于机器学习的通常评分模型(电话号码,电子邮件地址,家庭地址)而言不会被认为存在风险的特征可能成为基于图表的评分模型中的风险特征。
示例:3个电话号码相同的人,和其他邮箱地址相同的人联系在一起是不寻常的,而且存在潜在风险。电话号码的价值本身不会提供任何信息(因此,即使是最好的深度学习模型也不会从中获取任何价值),但个人通过相同的电话号码或电子邮件地址连接起来的事实可能是风险的同义词
我们在Python中这样做。
设置数据,清理和创建图表

这将是我们的模拟用户数据库
所以你从一个pandas DataFrame开始
import pandas as pd
df = pd.DataFrame({'ID':[1,2,3,4,5,6],
'First Name':['Felix', 'Jean', 'James', 'Daphne', 'James', 'Peter'],
'Family Name': ['Revert', 'Durand', 'Wright', 'Hull', 'Conrad', 'Donovan'],
'Phone number': ['+33 6 12 34 56 78', '+33 7 00 00 00 00', '+33 6 12 34 56 78', '+33 6 99 99 99 99', '+852 0123 4567', '+852 0123 4567'],
'Email': ['felix.revert@gmail.com', 'jean.durand@gmail.com', 'j.custom@gmail.com', pd.np.nan, 'j.custom@gmail.com', pd.np.nan]})
数据以df加载。现在,做一些准备。您需要连接具有相同电话号码和相同电子邮件的个人(由其ID表示)。我们首先从电话号码开始:
column_edge = 'Phone number'
column_ID = 'ID'
data_to_merge = df[[column_ID, column_edge]].dropna(subset=[column_edge]).drop_duplicates() # select columns, remove NaN
# To create connections between people who have the same number,
# join data with itself on the 'ID' column.
data_to_merge = data_to_merge.merge(
data_to_merge[[column_ID, column_edge]].rename(columns={column_ID:column_ID+"_2"}),
on=column_edge
)
我们的数据看起来像这样:

我们有一些联系,但是有两个问题:
- 每个人都与自己联系在一起
- 当X和Y相连时,Y也和X相连,同一个连接有两行
让我们清理一下:
# By joining the data with itself, people will have a connection with themselves.
# Remove self connections, to keep only connected people who are different.
d = data_to_merge[~(data_to_merge[column_ID]==data_to_merge[column_ID+"_2"])] \
.dropna()[[column_ID, column_ID+"_2", column_edge]]
# To avoid counting twice the connections (person 1 connected to person 2 and person 2 connected to person 1)
# we force the first ID to be "lower" then ID_2
d.drop(d.loc[d[column_ID+"_2"]<d[column_ID]].index.tolist(), inplace=True)
我们的数据现在看起来像这样:

1和3连接,5和6也连接。我们对电子邮件地址也这样做(文章末尾分享的完整代码)。现在让我们构建一个图表。我将在这里只分享代码的简单部分,因为添加不同的链接类型有点棘手。
import networkx as nx
G = nx.from_pandas_edgelist(df=d, source=column_ID, target=column_ID+'_2', edge_attr=column_edge)
G.add_nodes_from(nodes_for_adding=df.ID.tolist())
现在让我们可视化我们的数据。
使用networkx进行图形可视化
简单的nx.draw(G)给出了以下内容:

但是,我们看不出谁是哪个,有什么链接。我们来定制它:
nx.set_node_attributes(G, {row[column_ID]:{'Name': row['First Name'] +' '+ row['Family Name']} for i,row in df.iterrows()})
EDGE_SIZE = {
'Phone number': 2,
'Email': 1,
}
EDGE_COLOR = {
'Phone number': 'purple',
'Email': 'red',
}
def clean_edge(edge):
s.edge[edge[0], edge[1]].values()
def c_(list_edges): return [a for a in list_edges if a in list(EDGE_COLOR.keys())]
# For nx.Graph()
def edge_sizes(s): return [EDGE_SIZE[c_(list(s.edges[edge[0], edge[1]].keys()))[-1]] for edge in s.edges()] # /!\ multiple links => one size
def edge_colors(s): return [EDGE_COLOR[c_(list(s.edges[edge[0], edge[1]].keys()))[-1]] for edge in s.edges()] # /!\ multiple links => one color
# For nx.MultiDiGraph()
# def edge_sizes(s): return [EDGE_SIZE[s.edge[edge[0]][edge[1]][0]['label']] for edge in s.edges()] # /!\ multiple links => one size
# def edge_colors(s): return [EDGE_COLOR[s.edge[edge[0]][edge[1]][0]['label']] for edge in s.edges()] # /!\ multiple links => one color
def draw(s):
pos = nx.spring_layout(s, scale=0.5)
node_labels = dict((n,d['Name']) for n,d in s.nodes(data=True))
# labels = {**node_labels, **edge_labels}
nx.draw(s, pos=pos, width=edge_sizes(s), edge_color=edge_colors(s), alpha=0.8, arrows=False, node_color='lightgrey', node_size=400,
labels=node_labels,
font_color='black', font_size=8, font_weight='bold',
)
edge_labels = dict(((u,v),list(d.values())[0]) for u,v,d in G.edges(data=True))
nx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, font_size=8)
draw(nx.ego_graph(G=G, n=1, radius=3))

4个人通过2个不同的电话号码和1个电子邮件地址连接在一起......还应该进行更多的调查!
实现真正生成化的下一步
让我们回顾一下我们做过的事情:
- 从我们的用户数据库创建图表
- 自定义可视化,帮助我们看到奇怪的模式
如果您是业务驱动的,并希望一些专家使用您已经完成的工作,那么您的下一个重点应该是:
- 查找多个人连接在一起的过程的自动化,或风险模式检测
- 通过图形可视化和原始数据自动创建可视化和创建自定义仪表板的过程
危险的模式检测
这里有两种方法:
- 从那些你认为有风险的人开始检查他们和其他人的关系。与机器学习相关的是一种“监督”方法。更进一步,您还可以从机器学习评分开始(例如使用XGBoost),并查找它们之间的密切联系。
- 从奇怪的模式(太多的连接, dense network...)。这将是“无监督”的方法。
在我们的例子中,我们没有已知的欺诈者,所以我们将采用第二种方法。
Networkx已经实现了完全正确的算法:degree(),centrality(),pagerank(),connected_components()......我让你定义如何在数学上定义风险。
为业务创建可视化和自动化分析
对于大多数数据科学家来说,这听起来是老派,但快速做到这一点的方法就是在Excel中。
xlsxwriter包可帮助您粘贴危险人物图表中的数据,并将我们创建的图表图像直接粘贴到Excel文件中。您将获得每个风险网络的仪表板,如下所示:

对于每个具有潜在风险的网络,您可以自动创建仪表板,让专家完成他们的工作。您可以在信息中心中添加一些指标:涉及的人数,不同电话号码的数量,电子邮件地址......
更多详细源码地址:https://github.com/FelixChop/MediumArticles/blob/master/Graph_analysis_Python.ipynb