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计算公式:
(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大同小异,具体可参考官方文档说明。在上一篇文章中已经列出了所有算法的文档地址。