暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

技术专栏 | 大规模图计算应用研究

TalkingData 2017-11-16
224


1

前言


这次分享主要关于两个方面,一个方面是借助于图,通过分析人与行为的关系,进行行为预测,比如欺诈,羊毛党。第二个方面是借助于图,通过分析人与物的关系,进行推荐。


2

用图进行行为预测


2.1. 业内使用图进行反欺诈的场景


主要有以下场景:

根据一度关系和二度关系是否触及了欺诈用户;经济行为是否关联到了异常的商家;一机多人;多头贷款;使用pagerank算法对与借款用户相关的用户进行排名;识别组团欺诈;寻找失联用户的社交网络;


2.2. 使用 neo4j 进行行为预测


经过调研发现,neo4jcypher语言,图的表达能力简洁而强大,相比sparkgraphx,更容易建模。cypher语言支持一个图中创建多种实体(graphx中叫顶点),多种关系(graphx中叫边)。有丰富的语法、函数、支持存储过程、支持UDF。支持索引、ACID,是一个OLTP数据库。

Neo4j社区提供了存储过程能用于图算法。比如PageRankLPAConnected Components等等。还有一个开源项目Mazerunner用于实现neo4jspark的集成。

 

2.2.1. 用neo4j 实现羊毛党预测


我写了一个Demo实现羊毛党的预测:

1 建模以及造数

下面的代码 实现了创建实体以及关系。

create (p01:person { Name:"zhangsan",gender:"male", age:23,Econnoisseur:"true" })

 create (p02:person { Name:"lisi", gender:"male", age:23,Econnoisseur:"false"})

 create (p03:person { Name:"wangwu", gender:"male",age:23,Econnoisseur:"false" })

 create (p04:person { Name:"liuliu", gender:"male",age:23,Econnoisseur:"false" })

 create (p05:person { Name:"zhangyi", gender:"male",age:31,Econnoisseur:"false" })

 create (p06:person { Name:"zhanger", gender:"male",age:23,Econnoisseur:"true" })

 create (p07:person { Name:"zhangsi", gender:"male",age:23,Econnoisseur:"false" })

 create (p08:person { Name:"zhangwu", gender:"male",age:23,Econnoisseur:"false" })

 ……

 

create (p20:person { Name:"zhang17", gender:"male",age:23,Econnoisseur:"false" }) , (p01)-[:call{callstart:"1453187371",callnum:20}]->(p02), (p02)-[:call{callstart:"1453187371",callnum:30}]->(p01), (p01)-[:call{callstart:"1453187371",callnum:1}]->(p03), (p01)-[:call{callstart:"1453187371",callnum:1}]->(p04), (p01)-[:call{callstart:"1453187371",callnum:30}]->(p05), (p05)-[:call{callstart:"1453187371",callnum:30}]->(p01), (p06)-[:call{callstart:"1453187371",callnum:20}]->(p07), (p06)-[:call {callstart:"1453187371",callnum:30}]->(p08),(p06)-[:call {callstart:"1453187371",callnum:1}]->(p09),(p06)-[:call {callstart:"1453187371",callnum:1}]->(p10),(p06)-[:call {callstart:"1453187371",callnum:30}]->(p11),(p06)-[:call {callstart:"1453187371",callnum:30}]->(p12),(p09)-[:call {callstart:"1453187371",callnum:20}]->(p10),(p10)-[:call {callstart:"1453187371",callnum:20}]->(p09),(p06)-[:call {callstart:"1453187371",callnum:20}]->(p07),(p06)-[:call {callstart:"1453187371",callnum:30}]->(p08),(p06)-[:call {callstart:"1453187371",callnum:1}]->(p09),(p06)-[:call {callstart:"1453187371",callnum:1}]->(p10),(p06)-[:call {callstart:"1453187371",callnum:30}]->(p11),(p06)-[:call {callstart:"1453187371",callnum:30}]->(p12),(p09)-[:call {callstart:"1453187371",callnum:20}]->(p10),(p10)-[:call{callstart:"1453187371",callnum:20}]->(p09),(p13)-[:call{callstart:"1453187371",callnum:1}]->(p14)

 ,

……

 return *

 

match(p08:person { Name:"zhangwu"})

create (p08) - [r:transferMoney] ->(m01:merchant {Name:"companyA",FraudState:true})

return p08,r,m01 

 

所有实体和关系如下图所示:


2.有两种实体,person(人)和merchant(商户)。

有两种关系call(打电话)和transferMoney(转账)。实体用蓝色表示,关系用绿色表示。

Person上有四个属性Name genderageEconnoisseur(是否是羊毛党) Call 上有两个属性callstartcallnumMerchant上有两个属性,NameFraudState


3.预测羊毛党规则一:

有羊毛党标签的人或者被标为羊毛党的人打了超过60次电话的人

match  (p:person)-[r:call] ->(q)  where p.Econnoisseur = "true" andr.callnum >= 60

return q

union

match (p:person) wherep.Econnoisseur = "true"

return p as q


4.预测羊毛党规则二:

有羊毛党标签的人或者与羊毛党人打过或被打过20次电话的人

match  (p:person)-[r:call] -(q)  where p.Econnoisseur = "true" andr.callnum >= 20

returnq

union

match(p:person) where p.Econnoisseur = "true"

return p as q


5.预测羊毛党规则三:有羊毛党标签的人或者 与羊毛党人超过60次联系的人

match  (p:person)-[r:call] -(q) with p , q, sum(r.callnum)as num where p.Econnoisseur = "true" and num >= 60

return q , num

union

match (p:person) wherep.Econnoisseur = "true"

return p as q,0 as num


6.预测羊毛党规则四:

有羊毛党标签的人或者与两个以上羊毛党人有过联系的人

match (p:person)-[r:call] -(q)with p,q,count(distinct r) as num where p.Econnoisseur = "true" and num >= 2

return q,num

union

match (p:person) wherep.Econnoisseur = "true"

return p as q,0 as num


7.预测羊毛党规则五:

与欺诈状态的商户进行过转账交易的人

match (p:person)-[r:transferMoney] - (m:merchant)

where m.FraudState = true

return p,r,m


总结:

从实践上来看,neo4j建模非常灵活,表达能力也很强。可以基于一度二度关系或者二度以上关系,以及关系的聚合进行图分析。


2.2.2. Neo4j + pagerank 预测欺诈用户


这个是从网上找到的,是业内其他公司用Neo4jpagerank预测欺诈用户。

apply是借过款的用户;Phone是手机实体;用户与手机之间的关系是hasPhone

在本例子中有两种实体,一种关系。该算法是算出哪些用户与借款用户有关联关系,并根据关系进行打分排名。

排名高分段用户的坏账率是低分段用户的3.3倍。


代码如下:

match(n:apply) - [:hasPhone] -> (p:Phone)

with collect(p) as nodes

CALLapoc.algo.pageRankWithConfig(nodes,{iterations:6,types:'call'}) YIELDnode,score

with node,score

match (n:apply) - [:hasPhone] -> (node)

return distinct node.phone,n.category_cn,score

order by score desc


2.2.3. Neo4j graphgist提供的其他usecase


Neo4jgraphgist提供了很多neo4jusecase。可以参考这个例子发现neo4j的强大表达能力:https://neo4j.com/graphgist/d3a1e3af-d803-40f7-bafb-c49558a5cf0b#listing_category=fraud-detection



3

Neo4j 和 graphx 分别适合于哪些应用场景


Neo4j是一个OLTP的图数据库,他适合于选定一个起始顶点或者符合某个条件的某些起始顶点,做子图的遍历运算。从某个起始顶点或者多个起始顶点出发,做聚合也是可以的。因为支持索引,所以点查询性能很好,点查询支持高并发、低延时。 同时,neo4j上也有一些开源的存储过程,可以进行一些图算法,但是全图范围内的算法性能不高。

Graphx是一个OLAP的图算法库,他适合于进行全图范围的算法或者聚合运算。他不能进行更新。点查询性能也不高,点查询低并发、高延时。


4

用图进行推荐


4.1. 推荐算法概述


推荐算法主要包括以下几类:

1)基于内容的推荐:

这一类一般依赖于自然语言处理NLP的一些知识,通过挖掘文本的TF-IDF特征向量,来得到用户的偏好,进而做推荐。这类推荐算法可以找到用户独特的小众喜好,而且还有较好的解释性。比如你看了哈利波特I,基于内容的推荐算法发现哈利波特II-VI,与你以前观看的在内容上面(共有很多关键词)有很大关联性,就把后者推荐给你

 

2)协同过滤推荐:

协同过滤是推荐算法中目前最主流的种类,花样繁多,在工业界已经有了很多广泛的应用。它的优点是不需要太多特定领域的知识,可以通过基于统计的机器学习算法来得到较好的推荐效果。最大的优点是工程上容易实现,可以方便应用到产品中。目前绝大多数实际应用的推荐算法都是协同过滤推荐算法。

 

3)混合推荐:

这个类似我们机器学习中的集成学习,博才众长,通过多个推荐算法的结合,得到一个更好的推荐算法,起到三个臭皮匠顶一个诸葛亮的作用。比如通过建立多个推荐算法的模型,最后用投票法决定最终的推荐结果。混合推荐理论上不会比单一任何一种推荐算法差,但是使用混合推荐,算法复杂度就提高了,在实际应用中有使用,但是并没有单一的协同过滤推荐算法,比如逻辑回归之类的二分类推荐算法广泛。

 

4)基于规则的推荐:

这类算法常见的比如基于最多用户点击,最多用户浏览等,属于大众型的推荐方法,在目前的大数据时代并不主流。


4.2. 协同过滤


一般来说,协同过滤推荐分为三种类型:


第一种是基于用户(user-based)的协同过滤;

第二种是基于项目(item-based)的协同过滤;

第三种是基于模型(model based)的协同过滤。


前面两种在有些文章中叫做基于邻域的方法(Neighborhood-based)。


基于用户(user-based)的协同过滤主要考虑的是用户和用户之间的相似度,只要找出相似用户喜欢的物品,并预测目标用户对对应物品的评分,就可以找到评分最高的若干个物品推荐给用户。而基于项目(item-based)的协同过滤和基于用户的协同过滤类似,只不过这时我们转向找到物品和物品之间的相似度,只有找到了目标用户对某些物品的评分,那么我们就可以对相似度高的类似物品进行预测,将评分最高的若干个相似物品推荐给用户。比如你在网上买了一本机器学习相关的书,网站马上会推荐一堆机器学习,大数据相关的书给你,这里就明显用到了基于项目的协同过滤思想。


基于模型的协同过滤作为目前最主流的协同过滤类型,其相关算法可以写一本书了,当然我们这里主要是对其思想做有一个归类概括。我们的问题是这样的m个物品,n个用户的数据,只有部分用户和部分数据之间是有评分数据的,其它部分评分是空白,此时我们要用已有的部分稀疏数据来预测那些空白的物品和数据之间的评分关系,找到最高评分的物品推荐给用户。


基于模型(model based)的协同过滤也有多种方法,其中用矩阵分解做协同过滤是目前使用很广泛的一种方法。


4.3. 基于模型的协同过滤DEMO


 Spark build-in的推荐算法只有一个,是使用了基于模型的协同过滤算法。算法的原理在 http://blog.csdn.net/oucpowerman/article/details/49847979 说的比较明白,算法或者统计学比较好的同学可以看一下。


1)DEMO的数据集:从网上找到的bookcrossing数据集。数据集中有278858 个用户,271379本书,以及1149780个评分。

数据经过预处理之后,在mysql存储为三个表。



2)代码在bookcross.scala中,代码对数据库的数据抽取出来后,进行简单的特征工程,调用spark的算法,对某个人推荐书籍。

使用方法:

把要预测的人已经做的评分放到一个文件中上传到hdfs目录中。

           

               

然后调用

spark-submit --classBookCrossing   --jars/home/hadoop/jars/mysql-connector-java-5.1.36.jar --driver-class-path/home/hadoop/jars/mysql-connector-java-5.1.36.jar --executor-memory 10g--executor-cores 2  --driver-memory6g  --total-executor-cores 8/home/hadoop/changchun/spark_aux.jar /tmp/bc /tmp/bc/personalRatings.txt 进行预测。预测结果如下:


 

本周的技术分享就到这里,感谢观看!


文章转载自TalkingData,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论