PageRank值的和为1

计算图的pageRank值的和为1的前提条件是

1:每个节点分配的初始值的和为1.

2:计算公式的阿尔法的值需要除以节点的格式。

2:每个节点的out degree 不是是0;


第一个和第二个条件和我们编程时可以满足,第三个不是我们能决定的。如果不满足第三条件,那么就会有黑洞,往该节点上分配的值,就损失了。我们把out degree为0的节点称为黑洞节点。当然有些特殊的情况,和会大于一,比如所有节点都指向一个节点,没有其他的边。因为每个节点的值是固定的,每次把固定的值增加到指向的节点,那么和就会大于1.当然,这是比较特殊的情况。

其实和是否为1不重要,Graph中初始值为阿尔法值,而且计算PageRank时阿尔法也没有除以节点数。佩奇的论文中是除以节点数的。

如果我们必须要使PageRank的和为1,我们可以这样做,人为的为每个黑洞节点加上和其他节点的边。这样,就使所有的值参与运算,PageRank的和也就为1了。

如果我们再程序中直接加边,那么会使边额外的庞大,我们可以直接在计算时加入额外的值就可以了。每个黑洞节点贡献的值是节点值除以节点数-1(黑洞节点对其它所有节点)

那么每次的调整值为所有黑洞节点贡献值之和,代码为final double delta = outCount == count?0.0:rankGraph.vertices( ).toJavaRDD( ).filter( s-> !s._2( )._2( ))
.map( s-> s._2._1/(count-1)).reduce( (s1, s2)->s1 + s2 ); 做outCount == count判断是因为java的空集合不能与graph做join,scala就没有这个问题。

做最后的计算时,我们把调整加上去,如果是黑洞节点本身,那么需要减去节点本身的贡献值(节点值除以节点数-1),因为是其他黑洞节点的贡献,代码为

if (t2.isDefined( ))
{
double countValue = !t1._2?t2.get( ) + delta - t1._1( )/(count - 1):t2.get( ) + delta;
double value = resetProb/count + (1.0 - resetProb)*countValue;
return new Tuple2<Double, Boolean>(value, t1._2( ));
}
else
{
double value = resetProb/count + (1.0 - resetProb)*delta;
return new Tuple2<Double, Boolean>(value, t1._2( ));
}

如果是in degree的值为0的,那么计算值就是调整值。还有一个就是 in degree 和out degree都是0,那么这个节点应该在图中先处理掉是无用的,所以不考虑in degree 和out degree都为0的情况。

另外 做初始化时,取值黑洞节点应该小,程序取值为 阿尔法值除以节点数,可以加快收敛。

代码为

final double v1 = 1.0/outCount - resetProb*(count - outCount)/count/outCount; 
final double v2 = resetProb/count;


整个程序代码如下,


import java.io.Serializable;
import java.util.Arrays;


import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.graphx.Edge;
import org.apache.spark.graphx.EdgeContext;
import org.apache.spark.graphx.EdgeTriplet;
import org.apache.spark.graphx.Graph;
import org.apache.spark.graphx.TripletFields;
import org.apache.spark.graphx.VertexRDD;
import org.apache.spark.storage.StorageLevel;


import scala.Option;
import scala.Tuple2;
import scala.reflect.ClassManifestFactory;
import scala.reflect.ClassTag;
import scala.runtime.AbstractFunction0;
import scala.runtime.AbstractFunction1;
import scala.runtime.AbstractFunction2;
import scala.runtime.AbstractFunction3;
import scala.runtime.BoxedUnit;


/**
 * 
 */


public class FinalRageFunction
{
private static final ClassTag<S

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值