Spark Graphframes的社交关系图谱实战演练。我将结合自身开发和项目经验,分别讲述社交关系图谱原理、图计算原理、Spark Graphframes图计算编程、关联推荐实战等内容,帮助大家快速了解Spark Graphframes图计算的使用。有兴趣交流沟通的朋友,欢迎添加我个人微信: youlong525。1)业务通俗理解比如张三是个资深
我是谁? 我周围人是谁?我们有什么关系?
网络爱好者,也是个圈内达人。我们先来看看他的圈子:家庭圈、同事圈、朋友圈、区域圈、兴趣圈等。。
这些圈子中的角色对象。有的和张三关系紧密,如亲朋好友;有的毫不相识,即潜在对象;有的相隔万里却因相同的一个兴趣结识。。。
总体而言,这就是张三的社交关系图谱(简略版)。2)数据层面理解在理解社交关系图谱的业务含义后,我们去看看数据层面的含义。
个体属性 + 群体关系 => 关系图谱
群体关系和个体属性,从数据角度可抽象成包含多维度的数据标签。类似: 张三(name/age/sex)、朋友(friend/non-friend..)、同事(superior、colleague...)、区域(nearby、non-nearby)等。最终提炼成丰富的标签化的用户社交数据。| 关系 | 标签值 |
| 朋友 | 0(friend)、1(non-friend) ... |
| 同事 | 0(superior)、1(colleague) ... |
| 亲戚 | 0(parent)、1(non-parent) ... |
| 区域 | 0(nearby)、1(non-nearby)... |
社交关系图谱建设,一般会基于企业内人与人的关系数据梳理,通过对数据的类型、可信强度,不同来源的分析,构建统一的丰富的社交数据体系,形成关系知识图谱。数字化和标签化处理,抽象成带有标签的个体属性和关系数据。
再来看看此时的张三,包含属性特征和一组组的关系特征。程序中如何去实现呢?仔细看下,属性特征和关系特征数据在结构上符合图结构。
图由一个顶点集合和一条边(或者弧)集合组成,且每一条边都依附于顶点集合的两个顶点。
——来自百度百科
因此关系图谱数据在程序中可被抽象成"点——线"拓扑集合。基于此类数据结构的计算被称作图计算。
关系图谱数据转换为图数据结构后,一般会使用图计算组件进行开发。如下列举了生产中常见的图计算引擎特性,供大家参考。1)Neo4J
2)Spark GraphX
3)Spark GraphFrame
4)GraphFrames vs GraphX由于环境和项目技术选型所限,本文选择Spark Graphframes。大家也可以选择Spark Graphx,且GraphFrames和GraphX可相互转化。// GraphFrames转换为GraphX
val g: Graph[Row, Row] = gf.toGraphX()
// GraphX转换为GraphFrames
val gf: GraphFrame = GraphFrame.fromGraphX(g)Spark GraphX和Spark Graphframes的区别。| GraphFrames | GraphX | |
| 数据模型 | DataFrames | RDDs |
| 开发语言 | Scala/Java/Python | Scala |
| 使用场景 | 数据查询、图计算 | 图计算 |
| 顶点ID | Any Type | Long |
| 点边属性 | DataFrame columns | Any Type(VD, ED) |
| 返回类型 | GraphFrame、DataFrame | Graph[VD, ED] 、RDD[Long, VD] |
编程环境: Jupter
编程语言: Python
技术组件: Spark Graphframes
实现难度: 中等(可替换为Spark GraphX)
3.1 Spark graphframes基本语法GraphX中常用算法在GraphFrame的调用方法:1) 创建图对象(示例)// 定义顶点
vertices = spark.createDataFrame(
[("a", "Alice", 34), ("b", "Bob", 36)], \
["id", "name", "age"])
// 定义边
edges = spark.createDataFrame(
[("a", "b", "friend")] , ["src", "dst", "relationship"])
// 创建图对象
graph = GraphFrame(vertices,edges)// 计算顶点/边
graph.vertices.show()
graph.edges.show()
// 计算顶点度、出入度
graph.degrees.show()
graph.inDegrees.show()
graph.outDegrees.show()graph.vertices().filter("age > 30").show()
graph.edges.filter("type == friends").show()
graph.inDegrees.filter("inDegree >= 2").show()// 获取a->b的关系
motifs = graph.find("(a)-[e]->(b)")
motifs.show()// PageRank算法
graph.pageRank().maxIter() \
.resetProbability().run() \
.vertices().show()
// 广度优先算法
paths = graph.bfs("name='Alice'", "age > 34")
paths.show()
// 最短路径
graph.shortestPaths(landmarks=lm).show()
// 标签传播算法
graph.labelPropagation().show()关系图谱数据处理成图结构,且选择Spark Graphframes作为技术组件,下面开始实战演练。类似于物以类聚、人以群分的道理,有相同爱好、相同圈子的人可能是你感兴趣的人。这里举个例子:假如userA是zhangsan的朋友,userB是userA的朋友且不是zhangsan的朋友;userB和zhangsan有相同兴趣,则将userB推荐给zhangsan。
场景分析: 社交网络中,平台会推荐你关注人的喜爱物品,同时也会推荐关注人好友列表给你。

1)配置环境
逻辑分析: A->B and B -> C and A >< C,即A与B双向关系、B与C双向关系,但是A->C没有关系,输出(A,C)
from pyspark.sql import SparkSession
from pyspark import SparkContext
from graphframes import *
from pyspark.sql.functions import *
// 定义SparkContext
conf = SparkConf().set("", "")
// 添加graphframes-xx.jar依赖包
spark = SparkSession \
.builder \
.config(conf=conf) \
.config("spark.jar", "./graphframes-0.9.1-spark2.7-s_2.11.jar") \
.getOrCreate()
sc = spark.sparkContext// Vertics
v = spark.createDataFrame([
("a", "Alice", 34),
("b", "Bob", 36),
("c", "Charlie", 37),
("d", "David", 29),
("e", "Esther", 32),
("f", "Fanny", 38),
("g", "Gabby", 60)
], ["id", "name", "age"])
// Edges
e = spark.createDataFrame([
("a", "b", "follow"),
("a", "c", "friend"),
("a", "g", "friend"),
("b", "c", "friend"),
("c", "a", "friend"),
("c", "b", "friend"),
("c", "d", "follow"),
("c", "g", "friend"),
("d", "a", "follow"),
("d", "g", "friend"),
("e", "a", "follow"),
("e", "d", "follow"),
("f", "b", "follow"),
("f", "c", "follow"),
("f", "d", "follow"),
("g", "a", "friend"),
("g", "c", "friend"),
("g", "d", "friend")
], ["src", "dst", "relationship"])
// Create a GraphFrame
g = GraphFrame(v, e)// 计算关联好友
relationG = g.find("(a)-[ab]->(b)") \
.dropDuplicates() \
.selectExpr("a.name as user", "b.name as recommended_user")
// 计算推荐好友
// recommend = g.find("(a)-[ab]->(b);(b)-[bc]->(c); !(a)-[ac]->(c);")
recommend = g.find("(a)-[ab]->(b);(b)-[bc]->(c)") \
.filter("a.id != c.id") \
.filter("ab.relationship = 'follow' \
and bc.relationship = 'friend'") \
.dropDuplicates() \
.selectExpr("a.name as user", "c.name as recommended_user") \
.subtract(relationG)result = recommend.rdd.map(
lambda x: (x["user"], x["recommended_user"]
)).sortBy(lambda x: x[0]).collect()
print(result)
推荐好友列表5)补充:获取社交好友圈数量
获取社交图谱关系链中 "[relationship=='friends']>=2" 的数量
chain = g.find("(a)-[ab]->(b);(b)-[bc]->(c);(c)-[cd]->(d)")
// 定义更新状态条件,关系为friends则+1
sumChain = lambda cnt, relation: when(
relationship == 'friends', cnt + 1) \
.otherwise(cnt)
// 应用到chain,计算好友数量
condition = reduce(lambda cnt, sumChain(
cnt, col(e).relationship), \
["ab", "bc", "cd"], \
lit(0))
// 计算好友圈数
chainWithFriends = chain.where(condition >= 2)
chainWithFriends.show()社交维度的用户分析挖掘提供数据基础。同时基于多维度数据的特性,支持家庭关系、兴趣偏好等相关业务场景,可助力企业从客户维度、产品维度等提供拓客的数据支持。基于Spark Graphframes图计算技术,可快速实现企业级社交关系图谱项目的实施落地。本文内容仅供参考,关于项目的技术细节和问题后续再继续补充。如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195
我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正