基于Spark GraphX的图形数据分析

1 篇文章 0 订阅

一、图(Graph)

  • 为什么需要图计算
    • 许多大数据以大规模图或网络的形式呈现
    • 许多非图结构的大数据,常会被转换为图模型进行分析
    • 图数据结构很好地表达了数据之间的关联性
1.1 图(Graph)的基本概念
  • 图是由顶点集合(vertex)及顶点间的关系集合(边edge)组成的一种网状数据结构
    • 通常表示为二元组:Gragh=(V,E)
    • 可以对事物之间的关系建模
  • 应用场景
    • 在地图应用中寻找最短路径
    • 社交网络关系
    • 网页间超链接关系
1.2 图的术语

1.2.1 顶点和边
在这里插入图片描述
上面的图可以了解到图Graph包含三个顶点,即v1,v2,v3,每个顶点间各有一条互相关联的边,即下方所表述的意思。

Graph=(V,E)	
集合V={v1,v2,v3}	
集合E={(v1,v2),(v1,v3),(v2,v3)}

1.2.2 有向图和无向图

  • 有向图
    在这里插入图片描述
    代码表述即:
G=(V,E)
V={A,B,C,D,E}
E={<A,B>,<B,C>,<B,D>,<C,E>,<D,A>,<E,D>}
  • 无向图
    在这里插入图片描述
    代码表述即:
G=(V,E)
V={A,B,C,D,E}
E={(A,B),(A,D),(B,C),(B,D),(C,E),(D,E)}

1.2.3 有环图和无环图

  • 有环图
    • 包含一系列顶点连接的回路(环路)
      在这里插入图片描述
  • 无环图
    • DAG即为有向无环图
      在这里插入图片描述

1.2.4 度

  • 出度: 指从当前顶点指向其他顶点的边的数量
  • 入度: 其他顶点指向当前顶点的边的数量
    • 以下图为例,我们可以看到,11号顶点的度是最多的。共有5个度,其中出度3条,出向顶点2,顶点9和顶点10,入度2个,分别来自顶点5和顶点7。在这里插入图片描述
1.3 图的经典表示法

邻接矩阵

规则

  • 1、对于每条边,矩阵中相应单元格值为1
  • 2、对于每个循环,矩阵中相应单元格值为2,方便在行或列上求得顶点度数

由上方的规则,我们可以将下方的图转换成右边的二维矩阵。
在这里插入图片描述

二、Spark GraphX

2.1 简介
  • GraphX是Spark提供分布式图计算API
  • GraphX特点
    • 基于内存实现了数据的复用与快速读取
    • 通过弹性分布式属性图(Property Graph)统一了图视图与表视图
    • 与Spark Streaming、Spark SQL和Spark MLlib等无缝衔接
2.2 GraphX核心抽象
  • 弹性分布式属性图(Resilient Distributed Property Graph)
    • 顶点和边都带属性的有向多重图在这里插入图片描述
    • 一份物理存储,两种视图在这里插入图片描述
  • 对Graph视图的所有操作,最终都会转换成其关联的Table视图的RDD操作来完成

三、GraphX API

3.1 创建Graph

3.1.1 我们以下面这张图作为案例来进行创建图
在这里插入图片描述

  • 我们通过图可以看出,四个顶点Id分别为,3,7,5,2,他们的property都是一个包含name和job,而他们的关系也可以通过图的edge来获取到,所以我们可以得到下面的创建图标的代码。
val users: RDD[(Long, (String, String))] = sc.parallelize(
  Array(
    (3L, ("rxin", "student")),
    (7L, ("jgonzal", "postdoc")),
    (5L, ("franklin", "professor")),
    (2L, ("istoica", "professor")))
)
val relationship: RDD[Edge[String]] = sc.parallelize(
  Array(
    Edge(3, 7, "Collaborator"),
    Edge(5, 3, "Advisor"),
    Edge(2, 5, "Colleague"),
    Edge(5, 7, "PI"))
)
val userGraph = Graph(users,relationship)

3.1.2 通过加载文件的方式创建图
示例文件follwers.txt内容:

2 3
3 4
1 4
2 4

创建图代码如下:

import org.apache.spark.graphx.GraphLoader
val graphLoad = GraphLoader.edgeListFile(sc,"file:opt/kb09file/follwers.txt")
  • 加载边列表文件创建图,文件每行描述一条边,格式:srcId dstId。顶点与边的属性均为1
3.2 查看图信息

3.2.1 查看图顶点、边和图数据信息

  • 关键字:
    • 顶点:vertices
    • 边:edge
    • 图:triplets

我们通过上面的操作已经得到了两个图,我们查看一下userGraph这张图的信息。

println("顶点数据------")
userGraph.vertices.collect.foreach(println)
println("边数据------")
userGraph.edges.collect.foreach(println)
println("图数据------")
userGraph.triplets.collect.foreach(println)

/**
顶点数据------
(2,(istoica,professor))
(3,(rxin,student))
(5,(franklin,professor))
(7,(jgonzal,postdoc))
边数据------
Edge(3,7,Collaborator)
Edge(5,3,Advisor)
Edge(2,5,Colleague)
Edge(5,7,PI)
图数据------
((3,(rxin,student)),(7,(jgonzal,postdoc)),Collaborator)
((5,(franklin,professor)),(3,(rxin,student)),Advisor)
((2,(istoica,professor)),(5,(franklin,professor)),Colleague)
((5,(franklin,professor)),(7,(jgonzal,postdoc)),PI)
*/

3.2.2 顶点数量、边数量、度、入度、出度

  • 关键字:
    • 顶点数量:numVertices
    • 边数量:numEdges
    • 度:degrees
    • 入度:inDegrees
    • 出度:outDegrees

继续以上面的userGraph为例。

println("定点数--------")
println(userGraph.numVertices)
println("边数--------")
println(userGraph.numEdges)
println("度--------")
userGraph.degrees.collect.foreach(println)
println("入度--------")
userGraph.inDegrees.collect.foreach(println)
println("出度--------")
userGraph.outDegrees.collect.foreach(println)

/**
定点数--------
4
边数--------
4
度--------
(2,1)
(3,2)
(5,3)
(7,2)
入度--------
(3,1)
(5,1)
(7,2)
出度--------
(2,1)
(3,1)
(5,2)
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值