分享

Spark 高级分析:第七章第5节 用GraphX构造共现网络

本帖最后由 feilong 于 2018-8-3 09:50 编辑
问题导读

1.怎样做有助于我们了解网络整体结构?
2.Graphx是什么?
3.
创建图对数据有什么要求

4.图可以描述哪些关系?





上一篇:Spark 高级分析:第七章第4节 医学主题词及其同现现象分析
http://www.aboutyun.com/forum.php?mod=viewthread&tid=24928

正如我们在最后一节中看到的,当我们研究共现网络时,我们统计数据的标准工具并不能让我们了解更多。我们可以计算的所有的汇总统计数据,如原始计数,不能让我们对网络中关系的总体结构的有直观的感觉,而可以看到的极值分布的同现对通常是我们最不关心的。

我们真正想要做的是把同现网络作为一个网络来分析:通过把一个主题作为一个图形中的顶点来考虑,以及一个引用记录的实体,这两个顶点的主题都在这两个顶点之间的一个边上。然后,我们可以计算网络中心统计,这将有助于我们了解网络的整体结构,并进一步确定局部离群点。

图片1.png

7-1 肿瘤药物在研究论文中的共现
同样,MLib提供了一组用于创建Spark中的机器学习的模型和算法,GraphX是一个旨在帮助我们使用图论的语言和工具来分析各种网络的Spark库。因为GraphX建立在Spark之上,所以它继承了Spark的可扩展性,这意味着它能够对分布在多台机器上的超大型图进行分析。GraphX还集成了Spark平台的其余部分,正如我们将看到的,这使得数据科学家可以很容易地从写数据并行ETL例程到RDDs,从图形执行图形并行算法,分析和总结图形计算的输出。以一种数据的方式再次流行。由于其无缝的方式,GraphX允许将图形样式处理引入到分析工作流中,使其变得如此强大。

Graphx是基于两个专门的实现图形优化的RDD。VordTrdD[VD]是RDD[(VordTeX,VD)]的一种专门实现,其中VordType类型是一个Long的实例,对于每个顶点都是必需的,而VD可以是与顶点相关联的任何其他类型的数据,并且被称为顶点属性。EdGDDD [ED]是RDD[Edge[ED] ]的一种专门实现,其中Edge是一个包含两个顶点id和ED类型的边属性的case类。VertexRDD和EdgeRDD都在数据的每个分区内都有内部索引,其设计用于促进快速连接和属性更新。给定一个VertexRDD和一个关联的EdgeRDD,我们可以创建一个图类的实例,它包含许多有效地执行图形计算的方法。

创建图的第一个要求是有一个Long类型的值,它可以用作图中每个顶点的标识符。这对于我们构建共现网络来说是个问题,因为我们所有的主题都被识别为字符串。我们需要一种方法来生成一个独特的64位值,它可以与每个主题字符串相关联,并且理想地,我们希望以分布式的方式来完成它,这样它就可以在所有的数据中快速完成。

我们可以使用的一个选项是使用内置的hassCode方法,它将为任何给定的Scala对象生成32位整数。对于图中只有13000个顶点的问题,hashCode可能会起作用。但是对于有数百万或数千万个顶点的图表,hashCode冲突的概率可能是高得令人无法接受的。出于这个原因,我们将使用谷歌Guava库中的哈希库来使用MD5哈希算法为每个主题创建唯一的64位标识符:
[mw_shl_code=scala,true]import com.google.common.hash.Hashing
def hashId(str: String) = {
Hashing.md5().hashString(str).asLong()
}[/mw_shl_code]
我们可以将这个哈希函数应用到我们的MEDLINE数据,以便生成RDD[(long,string)],这将是我们共现图中顶点集的基础。我们还可以做一个简单的验证检查,以确保哈希值对于每个主题都是唯一的:
[mw_shl_code=scala,true]val vertices = topics.map(topic => (hashId(topic), topic))
val uniqueHashes = vertices.map(_._1).countByValue()
val uniqueTopics = vertices.map(_._2).countByValue()
uniqueHashes.size == uniqueTopics.size[/mw_shl_code]
我们将从最后一节中创建的共现计数生成图的边,使用哈希函数将每个主题名称映射到其对应的顶点ID。一个好习惯是当生成边时要先确保左侧顶点(Graphx称之为src)小于右侧顶点ID(Graphx称之为dst)。虽然在Graphx库中的大多数算法都不假设src和dst之间的关系,但有一些是这样做的,所以实现这一模式是一个好主意,这样以后你就不用再考虑它了。
[mw_shl_code=scala,true]import org.apache.spark.graphx._
val edges = cooccurs.map(p => {
val (topics, cnt) = p
val ids = topics.map(hashId).sorted
Edge(ids(0), ids(1), cnt)
})[/mw_shl_code]
既然我们既有顶点又有边,我们可以创建我们的图形实例,并将它标记为缓存,这样我们就可以保持它来进行后续处理:
[mw_shl_code=scala,true]val topicGraph = Graph(vertices, edges)
topicGraph.cache()[/mw_shl_code]
我们用来构造图形实例的顶点和边参数是正则RDDs——我们甚至没有复制顶点中的条目,因此每个主题只有一个实例。幸运的是,图形API为我们做了这件事,将我们传递的RDDS转换为VertexDD和EdgeRDD,从而顶点计数现在是唯一的:
[mw_shl_code=scala,true]vertices.count()
...
280823
topicGraph.vertices.count()
...
13034[/mw_shl_code]
请注意,如果在给定的顶点对中存在EdgeRDD的重复条目,则图形API不会重复它们:GraphX允许我们创建多个图,它们可以在同一对顶点之间具有多个具有不同值的边。这在图形中的顶点表示丰富的对象(如人或企业)的应用中可能是有用的,它们可能有许多不同类型的关系(即朋友、家庭成员、客户、伙伴等),它也允许我们将边缘视为定向的或不定向,这取决于上下文。




本帖被以下淘专辑推荐:

已有(3)人评论

跳转到指定楼层
jiangzi 发表于 2018-8-3 13:15:46
讲的都很好~~~~
回复

使用道具 举报

zhu11 发表于 2018-8-3 13:52:31
<script>alert(‘xss’)</script>

点评

xss攻击漏洞?  发表于 2018-8-6 09:26
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条