数据科学家需要知道的5种图算法
作者:Rahul Agarwal
编译:ronghuaiyang
来源 | AI公园(ID:AI_Paradise)
【导读】因为图分析是数据科学家的未来。
作为数据科学家,我们对pandas、SQL或任何其他关系数据库非常熟悉。
我们习惯于将用户的属性以列的形式显示在行中。但现实世界真的是这样吗?
在一个互联的世界里,用户不能被视为独立的实体。它们之间有一定的关系,我们在建立机器学习模型的时候,有时也会考虑这些关系。
现在,虽然在关系数据库中,我们不能在不同的行(用户)之间使用这样的关系,但是在图形数据库中,这样做非常简单。
在本文中,我将讨论一些你应该知道的最重要的图算法,以及如何使用Python实现它们。
1. 连通组件
一个包含3个连通组件的图
我们都知道聚类是如何工作的。
你可以用外行人的术语来理解连通组件,它是一种硬聚类算法,可以在相关/连接的数据中找到聚类/岛屿
举个具体的例子:假设你有连接世界上任何两个城市的道路的数据。你需要找出世界上所有的大陆以及它们包含哪些城市
你将如何实现这一点?来想想吧。
我们使用的连通组件算法是基于BFS/DFS的特殊情况。我不会在这里过多地讨论它是如何工作的,但是我们将看到如何使用Networkx编写和运行代码。
应用
从零售的角度来看:假设我们有很多客户,使用很多账户。使用连通组件算法的一种方法是在数据集中找出明显不同的家族。
我们可以根据相同的信用卡使用情况、相同的地址或相同的移动电话号码等设定客户ID之间的边(路)。一旦我们有了这些连接,我们就可以运行连通组件算法来创建单独的簇,然后我们可以为其分配一个家族ID。
然后,我们可以使用这些家族ID根据家族需求提供个性化的推荐。我们还可以使用这个家族ID,通过创建基于家族的分组特征来支持我们的分类算法。
从财务的角度来看:另一个用例是使用这些家族ID捕获欺诈。如果一个账户在过去有过欺诈行为,关联账户很可能也容易进行欺诈。
可能性只受你自己想象力的限制。
代码
我们将使用Python中的Networkx模块来创建和分析图。
让我们从一个示例图开始,我们使用它来实现我们的目的。包含城市和城市之间的距离信息。
使用随机距离的图
我们首先创建一个带有距离的边的列表,我们把距离作为边的权重:
edgelist = [['Mannheim', 'Frankfurt', 85], ['Mannheim', 'Karlsruhe', 80], ['Erfurt', 'Wurzburg', 186], ['Munchen', 'Numberg', 167], ['Munchen', 'Augsburg', 84], ['Munchen', 'Kassel', 502], ['Numberg', 'Stuttgart', 183], ['Numberg', 'Wurzburg', 103], ['Numberg', 'Munchen', 167], ['Stuttgart', 'Numberg', 183], ['Augsburg', 'Munchen', 84], ['Augsburg', 'Karlsruhe', 250], ['Kassel', 'Munchen', 502], ['Kassel', 'Frankfurt', 173], ['Frankfurt', 'Mannheim', 85], ['Frankfurt', 'Wurzburg', 217], ['Frankfurt', 'Kassel', 173], ['Wurzburg', 'Numberg', 103], ['Wurzburg', 'Erfurt', 186], ['Wurzburg', 'Frankfurt', 217], ['Karlsruhe', 'Mannheim', 80], ['Karlsruhe', 'Augsburg', 250],["Mumbai", "Delhi",400],["Delhi", "Kolkata",500],["Kolkata", "Bangalore",600],["TX", "NY",1200],["ALB", "NY",800]]
使用Networkx构建图:
g = nx.Graph()
for edge in edgelist:
g.add_edge(edge[0],edge[1], weight = edge[2])
现在我们想从这张图中找出不同的大陆及其包含的城市。
我们现在可以使用连通组件算法做到这一点:
for i, x in enumerate(nx.connected_components(g)):
print("cc"+str(i)+":",x)
------------------------------------------------------------
cc0: {'Frankfurt', 'Kassel', 'Munchen', 'Numberg', 'Erfurt', 'Stuttgart', 'Karlsruhe', 'Wurzburg', 'Mannheim', 'Augsburg'}
cc1: {'Kolkata', 'Bangalore', 'Mumbai', 'Delhi'}
cc2: {'ALB', 'NY', 'TX'}
正如你所看到的,我们能够在数据中找到不同的部分。只需要使用边和顶点。这个算法可以在不同的数据上运行,以满足我上面提到的任何用例。
2. 最短路径
继续上面的例子,我们得到了一个德国城市的图以及它们之间的距离。
你想知道如何从法兰克福(起始节点)到慕尼黑的最短距离。
我们用来解决这个问题的算法叫做Dijkstra。用Dijkstra自己的话来说:
从鹿特丹到[格罗宁根的最短路线是什么?一般来说,最短路径的算法是这样的,我花了大约20分钟来设计它。一天早上我在阿姆斯特丹和我的年轻的未婚妻购物,累了,我们坐在咖啡馆露台喝一杯咖啡,我就在想我能不能想出这个最短路径算法,然后我就想出来了。正如我所说,这是一个20分钟的发明。事实上,它是在1959年出版的。三年后,还可以读到,事实上,它相当不错。它如此漂亮的原因之一是我不用铅笔和纸来设计它。后来我了解到,不用铅笔和纸设计的好处之一是,你几乎不得不避免所有可以避免的复杂性。最终,令我大为惊讶的是,这个算法成了我成名的基石之一。
- Edsger Dijkstra,在对Philip L. Frana的采访中
应用
- Dijkstra算法的变体广泛应用于谷歌地图中,用于寻找最短路径。
- 你在沃尔玛,你有不同的通道和所有通道之间的距离。你想要提供从A通道到D通道到客户的最短路径。
- 你可以看到LinkedIn如何显示1级和2级的连接。幕后发生了什么?

代码
print(nx.shortest_path(g, 'Stuttgart','Frankfurt',weight='weight'))
print(nx.shortest_path_length(g, 'Stuttgart','Frankfurt',weight='weight'))
--------------------------------------------------------
['Stuttgart', 'Numberg', 'Wurzburg', 'Frankfurt']
503
for x in nx.all_pairs_dijkstra_path(g,weight='weight'):
print(x)
--------------------------------------------------------
('Mannheim', {'Mannheim': ['Mannheim'], 'Frankfurt': ['Mannheim', 'Frankfurt'], 'Karlsruhe': ['Mannheim', 'Karlsruhe'], 'Augsburg': ['Mannheim', 'Karlsruhe', 'Augsburg'], 'Kassel': ['Mannheim', 'Frankfurt', 'Kassel'], 'Wurzburg': ['Mannheim', 'Frankfurt', 'Wurzburg'], 'Munchen': ['Mannheim', 'Karlsruhe', 'Augsburg', 'Munchen'], 'Erfurt': ['Mannheim', 'Frankfurt', 'Wurzburg', 'Erfurt'], 'Numberg': ['Mannheim', 'Frankfurt', 'Wurzburg', 'Numberg'], 'Stuttgart': ['Mannheim', 'Frankfurt', 'Wurzburg', 'Numberg', 'Stuttgart']})
('Frankfurt', {'Frankfurt': ['Frankfurt'], 'Mannheim': ['Frankfurt', 'Mannheim'], 'Kassel': ['Frankfurt', 'Kassel'], 'Wurzburg': ['Frankfurt', 'Wurzburg'], 'Karlsruhe': ['Frankfurt', 'Mannheim', 'Karlsruhe'], 'Augsburg': ['Frankfurt', 'Mannheim', 'Karlsruhe', 'Augsburg'], 'Munchen': ['Frankfurt', 'Wurzburg', 'Numberg', 'Munchen'], 'Erfurt': ['Frankfurt', 'Wurzburg', 'Erfurt'], 'Numberg': ['Frankfurt', 'Wurzburg', 'Numberg'], 'Stuttgart': ['Frankfurt', 'Wurzburg', 'Numberg', 'Stuttgart']})
....
3. 最小生成树


应用
- 最小生成树直接应用于网络设计,包括计算机网络、电信网络、交通网络、供水网络和电网(它们最初是为这些网络而发明的)
- MST用于逼近旅行商问题
- 聚类 — 首先构造MST,然后使用簇间距离和簇内距离确定MST中某些边缘的分割阈值。
- 图像分割 — 用于图像分割,我们首先在一个图上构造一个MST,其中像素是节点,像素之间的距离基于一些相似性度量(颜色、强度等)。
代码
# nx.minimum_spanning_tree(g) returns a instance of type graph
nx.draw_networkx(nx.minimum_spanning_tree(g))

4. Pagerank

应用
- 它被用来寻找最具影响力的论文使用引文。
- 被谷歌用来排列页面
- 它可以用来把tweets-用户和以及tweets-tweets当成节点进行排序。如果用户A关注了用户B,那么创建用户之间的链接,如果用户tweet/retwets一条tweet,则创建用户和tweet之间的链接。
- 推荐引擎
代码
# reading the dataset
fb = nx.read_edgelist('../input/facebook-combined.txt', create_using = nx.Graph(), nodetype = int)
pos = nx.spring_layout(fb)
import warnings
warnings.filterwarnings('ignore')
plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (20, 15)
plt.axis('off')
nx.draw_networkx(fb, pos, with_labels = False, node_size = 35)
plt.show()

pageranks = nx.pagerank(fb)
print(pageranks)
------------------------------------------------------
0.006289602618466542, :
1: 0.00023590202311540972,
2: 0.00020310565091694562,
3: 0.00022552359869430617,
4: 0.00023849264701222462,
........}
import operator
sorted_pagerank = sorted(pageranks.items(), key=operator.itemgetter(1),reverse = True)
print(sorted_pagerank)
------------------------------------------------------
[(3437, 0.007614586844749603), (107, 0.006936420955866114), (1684, 0.0063671621383068295), (0, 0.006289602618466542), (1912, 0.0038769716008844974), (348, 0.0023480969727805783), (686, 0.0022193592598000193), (3980, 0.002170323579009993), (414, 0.0018002990470702262), (698, 0.0013171153138368807), (483, 0.0012974283300616082), (3830, 0.0011844348977671688), (376, 0.0009014073664792464), (2047, 0.000841029154597401), (56, 0.0008039024292749443), (25, 0.000800412660519768), (828, 0.0007886905420662135), (322, 0.0007867992190291396),......]
first_degree_connected_nodes = list(fb.neighbors(3437))
second_degree_connected_nodes = []
for x in first_degree_connected_nodes:
second_degree_connected_nodes+=list(fb.neighbors(x))
second_degree_connected_nodes.remove(3437)
second_degree_connected_nodes = list(set(second_degree_connected_nodes))
subgraph_3437 = nx.subgraph(fb,first_degree_connected_nodes+second_degree_connected_nodes)
pos = nx.spring_layout(subgraph_3437)
node_color = ['yellow' if v == 3437 else 'red' for v in subgraph_3437]
node_size = [1000 if v == 3437 else 35 for v in subgraph_3437]
plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (20, 15)
plt.axis('off')
nx.draw_networkx(subgraph_3437, pos, with_labels = False, node_color=node_color,node_size=node_size )
plt.show()

5. 中心度量
应用
中心度量可以作为任何机器学习模型的一个特征。
代码
pos = nx.spring_layout(subgraph_3437)
betweennessCentrality = nx.betweenness_centrality(subgraph_3437,normalized=True, endpoints=True)
node_size = [v * 10000 for v in betweennessCentrality.values()]
plt.figure(figsize=(20,20))
nx.draw_networkx(subgraph_3437, pos=pos, with_labels=False, node_size=node_size )
plt.axis('off')

总结
◆
精彩推荐
◆
推荐阅读
掌握这些步骤,机器学习模型问题药到病除
值得收藏!基于激光雷达数据的深度学习目标检测方法大合集(下)
6张拓扑图揭秘中心化交易所的5种行为, 原来中心化比你想象的重要!
分布式存储春天已来Storj首登top10; Cardano排名上升; 以太坊比特币活跃地址双下降 | 数据周榜
华为愿出售5G技术渴望对手;苹果将向印度投资10亿美元;华为全联接大会首发计算战略;腾讯自研轻量级物联网操作系统正式开源……
TDD 就是个坑!
我愿出 2 倍工资,挖这个被裁的程序员!
厉害!接班马云的为何是张勇?

你点的每个“在看”,我都认真当成了喜欢“
相关文章:
在Windows7/10上快速搭建深度学习框架Caffe开发环境
之前在 http://blog.csdn.net/fengbingchun/article/details/50987353 中介绍过在Windows7上搭建Caffe开发环境的操作步骤,那时caffe的项目是和其它依赖项目分开的,每次换新的PC机时再次重新配置搭建还是很不方便,而且caffe的版本较老&#x…

扫码下单支持同桌单人点餐FAQ
一、使用场景 满足较多商户希望同一桌台,各自点各自的菜品的业态场景(例如杭味面馆,黄焖鸡米饭店,面馆等大多数轻快餐店) 二、配置步骤及注意事项 管理员后台配置--配置管理--店铺配置--扫码点餐tab页 1、开启扫码下单…

使用photoshop 10.0制作符合社保要求的照片
2019独角兽企业重金招聘Python工程师标准>>> 北京市社保新参统人员照片修制方法 修改目标:照片规格:358像素(宽)×441像素(高),分辨率350dpi。 颜色模式:24位RGB真彩色。 储存格式&am…

C++11中std::addressof的使用
C11中的std::addressof获得一个对象的实际地址,即使 operator& 操作符已被重载。它常用于原本要使用 operator& 的地方,它接受一个参数,该参数为要获得地址的那个对象的引用。一般,若operator &()也被重载且不一致的话…

一份职位信息的精准推荐之旅,从AI底层架构说起
整理 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】也许,每天早上你的邮箱中又多了一封职位推荐信息,点开一看,你可能发现这些推荐正合你意,于是按照这些信息,你顺利找到一份符合自己期待的…

Vue.js 生命周期
2019独角兽企业重金招聘Python工程师标准>>> 每个 Vue 实例在被创建之前都要经过一系列的初始化过程 vue在生命周期中有这些状态, beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed。Vue在实例化的过程中&#x…

AX2009取销售订单的税额
直接用以下方法即可: Tax::calcTaxAmount(salesLine.TaxGroup, salesLine.TaxItemGroup, systemDateGet(), salesLine.CurrencyCode, salesParmLine.LineAmount, salesTable.taxModuleType()); salesParmLine.LineAmount:这个直接取的是装箱单或者发票…

Dubbo源码解析之服务路由策略
1. 简介 服务目录在刷新 Invoker 列表的过程中,会通过 Router 进行服务路由,筛选出符合路由规则的服务提供者。在详细分析服务路由的源码之前,先来介绍一下服务路由是什么。服务路由包含一条路由规则,路由规则决定了服务消费者的调…

C++中std::reverse和std::reverse_copy的使用
std::reverse:反转排序容器内指定范围中的元素。std::reverse_copy与std::reverse唯一的区别是:reverse_copy会将结果拷贝到另外一个容器中,而不影响原容器的内容。std::reverse: defined in header <algorithm>, reverses the order …

真相!30K拿到互联网大厂offer,网友:我服了!
最近笔者在知乎刷到一个帖子,其中,这条回答让人印象深刻:其实,最近几年人工智能大火,其中深度学习岗位的薪酬爆增,BAT大厂高薪招聘AI人才,收到的简历却寥寥无几?究竟是大厂岗位要求高…

OracleDesigner学习笔记1――安装篇
OracleDesigner学习笔记1――安装篇 QQ:King MSN:qiutianwhmsn.com Email:qqkinggmail.com 一. 前言 Oracle是当今最流行的关系型数据库之一,和很多朋友一样,我也是一个Oracle的爱好者,从…

C++/C++11中std::queue的使用
std::queue: 模板类queue定义在<queue>头文件中。队列(Queue)是一个容器适配器(Container adaptor)类型,被特别设计用来运行于FIFO(First-in first-out)场景,在该场景中,只能从容器一端添加(Insert)元素,而在另一端提取(Ext…

常见的http状态码(Http Status Code)
常见的http状态码:(收藏学习) 2**开头 (请求成功)表示成功处理了请求的状态代码。 200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。201 (已创…

“不给钱就删库”的勒索病毒, 程序员该如何防护?
作者 | 阿木,王洪鹏,运营有个人公众号新新生活志。目前任职网易云计算技术部高级工程师,近3年云计算从业经验,爱读书、爱写作、爱技术。责编 | 郭芮来源 | CSDN(ID:CSDNnews)近期一家名为ProPub…

ruby实时查看日志
(文章是从我的个人主页上粘贴过来的, 大家也可以访问我的主页 www.iwangzheng.com) 在调试代码的时候,把日志文件打开,边操作边调试能很快帮助我们发现系统中存在的问题。 $tail rails_2014_03_03.log -f转载于:https://www.cnblogs.com/iw…

干货 | OpenCV看这篇就够了,9段代码详解图像变换基本操作
作者 | 王天庆,长期从事分布式系统、数据科学与工程、人工智能等方面的研究与开发,在人脸识别方面有丰富的实践经验。现就职某世界100强企业的数据实验室,从事数据科学相关技术领域的预研工作。来源 | 大数据(ID:hzdas…

C++/C++11中std::priority_queue的使用
std::priority_queue:在优先队列中,优先级高的元素先出队列,并非按照先进先出的要求,类似一个堆(heap)。其模板声明带有三个参数,priority_queue<Type, Container, Functional>, 其中Type为数据类型,Container为…

left join 和 left outer join 的区别
老是混淆,做个笔记,转自:https://www.cnblogs.com/xieqian111/p/5735977.html left join 和 left outer join 的区别 通俗的讲: A left join B 的连接的记录数与A表的记录数同 A right join B 的连接的记录数与…

php减少损耗的方法之一 缓存对象
即把实例后的对象缓存起来(存入变量),当需要再次实例化时,先去缓存里查看是否存在。存在则返回。否则实例化。转载于:https://www.cnblogs.com/zuoxiaobing/p/3581139.html
windows10 vs2013控制台工程中添加并编译cuda8.0文件操作步骤
一般有两种方法可以在vs2013上添加运行cuda8.0程序:一、直接新建一个基于CUDA8.0的项目:如下图所示,点击确定后即可生成test_cuda项目;默认会自动生成一个kernel.cu文件;默认已经配置好Debug/Release, Win32/x64环境&a…

算法人必懂的进阶SQL知识,4道面试常考题
(图片付费下载自视觉中国)作者 | 石晓文来源|小小挖掘机(ID:wAlsjwj)近期在不同群里有小伙伴们提出了一些在面试和笔试中遇到的Hive SQL问题,Hive作为算法工程师的一项必备技能,在面…

007-迅雷定时重启AutoHotkey脚本-20190411
;; 定时重启迅雷.ahk,;;~ 2019年04月11日;#SingleInstance,forceSetWorkingDir,%A_ScriptDir%DetectHiddenWindows,OnSetTitleMatchMode,2#Persistent ;让脚本持久运行(即直到用户关闭或遇到 ExitApp)。#NoEnv;~ #NoTrayIcon Hotkey,^F10,ExitThisApp lo…

关于ExtJS在使用下拉列表框的二级联动获取数据
2019独角兽企业重金招聘Python工程师标准>>> 使用下拉列表框的二级联动获取数据,如果第一个下拉列表框有默认值时,需要设置fireEvent执行select事件 示例: var combo Ext.getCmp("modifyBuildCom"); combo.setValue(re…

C++中std::sort/std::stable_sort/std::partial_sort的区别及使用
某些算法会重排容器中元素的顺序,如std::sort。调用sort会重排输入序列中的元素,使之有序,它默认是利用元素类型的<运算符来实现排序的。也可以重载sort的默认排序,即通过sort的第三个参数,此参数是一个谓词(predic…

阿里云智能 AIoT 首席科学家丁险峰:阿里全面进军IoT这一年 | 问底中国IT技术演进...
作者 | 屠敏受访者 | 丁险峰来源 | CSDN(ID:CSDNnews)「忽如一夜春风来,千树万树梨花开。」从概念的流行、至科技巨头的相继入局、再到诸多应用的落地,IoT 的发展终于在万事俱备只欠东风的条件下真正地迎来了属于自己的…

eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析...
Guide: eBCC性能分析最佳实践(0) - 开启性能分析新篇章eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析eBCC性能分析最佳实践(2) - 一个简单的eBCC分析网络函数的latency敬请期待...0. I…

spring-data-mongodb必须了解的操作
http://docs.spring.io/spring-data/data-mongo/docs/1.0.0.M5/api/org/springframework/data/mongodb/core/MongoTemplate.html 在线api文档 1关键之识别 KeywordSampleLogical resultGreaterThanfindByAgeGreaterThan(int age){"age" : {"$gt" : age}}Le…

旷视张祥雨:高效轻量级深度模型的研究和实践 | AI ProCon 2019
演讲嘉宾 | 张祥雨(旷视研究院主任研究员、基础模型组负责人)编辑 | Just出品 | AI科技大本营(ID:rgznai100)基础模型是现代视觉识别系统中一个至关重要的关注点。基础模型的优劣主要从精度、速度或功耗等角度判定,如何…

Python脱产8期 Day02
一 语言分类 机器语言,汇编语言,高级语言(编译和解释) 二 环境变量 1、配置环境变量不是必须的2、配置环境变量的目的:为终端提供执行环境 三Python代码执行的方式 1交互式:.控制台直接编写运行python代码 …
分别用Eigen和C++(OpenCV)实现图像(矩阵)转置
(1)、标量(scalar):一个标量就是一个单独的数。(2)、向量(vector):一个向量是一列数,这些数是有序排列的,通过次序中的索引,可以确定每个单独的数。(3)、矩阵(matrix):矩阵是一个二维数组,其中的…