Neo4j笔记(一)算法(2)PageRank

1、PageRank

PageRank最初是谷歌推出用来计算网页排名的,简单的说就是,指向这个网页的链接数越多,那么这个网页就越重要。但是很可能会有人自己制作一些垃圾网页设置大量的链接指向自己的网页来提高网页排名,这肯定是谷歌不希望看到的。因此PageRank还有一个迭代计算的过程,一个网页A虽然有大量的垃圾网页指向自己,但是这些垃圾网页是没有被指向的,因此迭代完以后A的得分也不会高。因此PageRank的计算基于两个假设:
(1)数量假设:一个节点(网页)的入度(被链接数)越大,页面质量越高
(2)质量假设:一个节点(网页)的入度的来源(哪些网页在链接它)质量越高,页面质量越高

PageRank在迭代之前会为每个网页赋予一个相同的初始值,假设有A、B、C、D四个网页,B、C、D都只指向A,则迭代一次以后A的PageRank值:PR(A) = PR(B)+PR(C)+PR(D)。如果B除指向A以外还指向另一个网页,D不指向A,则:PR(A) = PR(B)/2+PR(C)。

PageRank计算公式:
PR(A) = (1-d)+d(PR(T_{1})/C(T_{1})+...+PR(T_{n})/C(T_{n}))
(1)PR(A) 是页面A的PR值。
(2)PR(Tn)是页面Tn的PR值,在这里,页面Tn是指向A的所有页面中的某个页面。
(3)C(Tn)是页面Tn的出度,也就是Tn指向其他页面的边的个数。
(4)d 为阻尼系数,其意义是,在任意时刻,用户到达某页面后并继续向后浏览的概率,该数值是根据上网者使用浏览器书签的平均频率估算而得,可以设置在0和1之间,通常d=0.85。d的引入也和终止点问题、陷阱问题有关。
(5)关于PageRank的计算公式,存在不同版本,仅供参考。

PageRank的缺点:
第一, 没有区分站内导航链接。 很多网站的首页都有很多对站内其他页面的链接, 称为站内导航链接。 这些链接与不同网站之间的链接相比,肯定是后者更能体现PageRank值的传递关系。 
第二, 没有过滤广告链接和功能链接(例如常见的“分享到微博”)。这些链接通常没有什么实际价值, 前者链接到广告页面, 后者常常链接到某个社交网站首页。 
第三, 对新网页不友好。一个新网页的一般入链相对较少,即使它的内容的质量很高,要成为一个高PR值的页面仍需要很长时间的推广。

由于本文的目的不是介绍PageRank的原理,因此对于PageRank的介绍比较简单,PageRank的详细知识请参阅其他资料。

2、Neo4j PageRank

语法
algo中的算法都以过程形式调用,语法如下:

CALL algo.pageRank(label:String, relationship:String,
    {iterations:20, dampingFactor:0.85, write: true, writeProperty:'pagerank', concurrency:4})
YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, write, writeProperty

字段含义如下:

名称 类型 默认 是否可选 含义
label string null yes 加载的节点标签,如果为null,加载所有节点
relationship string null yes 加载的关系类型,如果为null,加载所有关系
iterations int 20 yes 迭代次数,默认20
concurrency int available CPUs yes 并发数量,默认CPU数
dampingFactor float 0.85 yes 阻尼系数,默认0.85
weightProperty string null yes 权重属性,pagerank既支持无权重,也支持有权重,默认无权重计算,该属性必须是数值型
defaultValue float 0.0 yes 权重的缺省值,如果某个关系没有指定的权重属性或者类型不对,则使用该值替代
write boolean true yes 是否将计算结果回写为节点属性,对于数据量很大的时候比较适用。一次计算,永久查询
graph string 'heavy' yes 使用label和关系类型指定数据集的时候使用'heavy';使用cypher语句指定数据集的时候(例如使用match匹配结果集)使用'cypher';默认计算有20亿个节点和20亿个关系的限制,如果图超过这个限制,使用'huge'

对于不熟悉的属性,建议都使用默认值。另外,Neo4j还支持以结果流的形式运行PageRank,不会回写到节点属性中,比较适合查看、调试:

CALL algo.pageRank.stream(label:String, relationship:String,
    {iterations:20, dampingFactor:0.85, concurrency:4})
YIELD node, score

Demo
流结果计算:

CALL algo.pageRank.stream('Page', 'LINKS', {iterations:20, dampingFactor:0.85})
YIELD nodeId, score

RETURN algo.getNodeById(nodeId).name AS page,score
ORDER BY score DESC

回写计算:

CALL algo.pageRank('Page', 'LINKS',
  {iterations:20, dampingFactor:0.85, write: true,writeProperty:"pagerank"})
YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, write, writeProperty

加权计算:

CALL algo.pageRank.stream('Page', 'LINKS', {
  iterations:20, dampingFactor:0.85, weightProperty: "weight"
})
YIELD nodeId, score

RETURN algo.getNodeById(nodeId).name AS page,score
ORDER BY score DESC

Personalized PageRank:
Personalized PageRank是PageRank的变体,偏向于一组sourceNodes

MATCH (siteA:Page {name: "Site A"})

CALL algo.pageRank.stream('Page', 'LINKS', {iterations:20, dampingFactor:0.85, sourceNodes: [siteA]})
YIELD nodeId, score

RETURN algo.getNodeById(nodeId).name AS page,score
ORDER BY score DESC

3、结语

其他算法的使用和PageRank大同小异,具体可参考官方文档说明。在上一篇文章中已经列出了所有算法的文档地址。

猜你喜欢

转载自blog.csdn.net/haveanybody/article/details/87915480
今日推荐