zoukankan      html  css  js  c++  java
  • PageRank网页价值算法

    一.简介

      PageRank是Google提出的算法,用于衡量特定网页相对于其它网页而言的重要程度。是Google创始人拉里.佩奇和谢尔盖.布林于1997年创造的,用于实现将链接价值概念作为排名的重要因素。

    二.算法原理

      1.入链

        PageRank让链接来投票,到一个页面的超链接相当于对该网页投一票。

      2.入链个数

        如果一个页面节点接收到的其它网页指向的入链数量越多,那么这个页面就越重要。

      3.入链质量

        指向页面A的不同入链质量不同,质量高的页面会通过链接向其它页面传递更大的权重。所有越是质量高的页面指向页面A,则页面A就越重要。

      4..图解

        

        1.站在A的角度:需要将自己的PR值分给B,D。

        2.站在B的角度:收到来自A,C,D的PR值。

        3.PR值需要迭代计算,且其PR值会逐渐趋于稳定。

      5.初始值

        1.Google的每个页面设置相同的PR值,PageRank算法类似,每个页面的PR初始值为1。

        2.迭代计算,Google不断的重复计算每个页面的PageRank,经过不断的迭代计算,这些页面的PR值会趋于稳定,这就是收敛的状态。

      6.收敛标准

        1.每个页面的PR值和上一次计算的PR值相等。

        2.设定一个差值指标【例如:0.001】,当所有页面上一次计算的PR值差值平均小于该标准时,则认为其已经收敛。

        3.设定一个百分比【例如:99%】,当99%的页面和上一次计算的PR值相等时认为其已收敛。

        

    三.修正PageRank

      1.站在互联网的角度看,只有出度而没有入度,PR值会趋向于0,只有入度而没有出度,PR值会趋向于很大。

      2.修正PageRank计算公式,增加阻尼系数,一般取值为d=0.85。

      3.完整PageRank计算公式:

        

        备注:

          d:阻尼系数

          M(i):指向i的页面集合

          L(i):页面的出链数

          PR(Pj):j页面的PR值

          n:所有页面数

    四.代码实现

     1 package big.data.analyse.pageRank
     2 
     3 import org.apache.log4j.{Level, Logger}
     4 import org.apache.spark.sql.SparkSession
     5 object PageRunJob {
     6   def main(args: Array[String]): Unit = {
     7     /**
     8       * 设置日志级别
     9       */
    10     Logger.getLogger("org").setLevel(Level.WARN)
    11     val spark = SparkSession.builder//创建spark入口
    12     .master("local[2]")//设置本地运行模式
    13     .appName("pageRank")
    14     .config("spark.sql.warehouse.dir","file:///D://warehouse")//设置本地仓库
    15     .getOrCreate()
    16     //读取关系矩阵
    17     val firstInputPath = spark.read.textFile("src/big/data/analyse/pageRank/pagerank.txt")
    18     // 求出n
    19     val n = firstInputPath.count()
    20     //获取所有节点
    21     val onlyKey = firstInputPath.rdd.map(line => line.split(",")(0))
    22     onlyKey.cache()//缓存(方便重用,后面多次使用时建议使用)
    23     //获取所有映射关系
    24     val kvMap = firstInputPath.rdd.map(line =>
    25     {
    26         val array = line.split(",").array
    27         (array(0),array(1))
    28     })
    29     kvMap.cache()//缓存(方便重用)
    30 
    31     val bk = onlyKey.map(k=>(k,1)).reduceByKey(_+_)
    32 
    33     val d = 0.85 // 阻尼系数
    34     //延迟加载
    35     val first = onlyKey.map(k=>(k,1.0)) // 默认每个网页初始价值为1
    36         .reduceByKey(_+_) // 求每个网页出度
    37         .map(line =>(line._1,((1-d)/n) + d * 1/line._2)) // 出度越大,价值越小
    38         .sortByKey()//排序
    39 
    40     first.cache()//缓存(方便重用)
    41     println("<<<<<<<<<<<<<<<<<<<正在进行第1迭代计算,当前误差为:"+first.count()+">>>>>>>>>>>>>>>>>>>")
    42     first.foreach(println)
    43 
    44     val frist_bk = first.join(bk)
    45       .map(row => (row._1,row._2._1/row._2._2)) // 重新平衡每个网页的出度价值
    46 
    47     var second = kvMap.join(frist_bk)
    48       .map(row => row._2)
    49       .reduceByKey(_+_)
    50       .sortByKey()//排序
    51 
    52     /**
    53       * 统计初次误差
    54       */
    55     val subValue = second.join(first).map(k=>k._2).sortByKey()
    56       .map(line =>(line._2-line._1).abs).sum()
    57     println("<<<<<<<<<<<<<<<<<<<正在进行第2迭代计算,当前误差为:"+subValue+">>>>>>>>>>>>>>>>>>>")
    58     second.foreach(println) // 二次计算每个网页的价值
    59 
    60     val precision = 0.001//设置精确度
    61     var i = 3
    62     while(true){
    63       val mid_bk = second.join(bk)
    64         .map(row => (row._1,((1-d)/n) + d * row._2._1/row._2._2)) // 重新平衡每个网页的出度价值
    65 
    66       val second_mid = kvMap.join(mid_bk)
    67         .map(row => row._2)
    68         .reduceByKey(_+_)
    69         .sortByKey()//排序
    70 
    71       val subValue = second_mid.join(second).map(k=>k._2).sortByKey()//计算当前迭代的各节点的价值
    72         .map(line =>(line._2-line._1).abs).sum()
    73 
    74       println("<<<<<<<<<<<<<<<<<<<正在进行第"+i+"迭代计算,当前误差为:"+subValue+">>>>>>>>>>>>>>>>>>>")
    75       second_mid.foreach(println) // 二次计算每个网页的价值
    76       if(subValue<=precision){
    77         println("<<<<<<<<<<<<<<<<<<<当前误差为:"+subValue+"已小于"+precision+",迭代完成!>>>>>>>>>>>>>>>>>>>")
    78          return
    79       }else{
    80         second = second_mid
    81          i += 1
    82       }
    83     }
    84     spark.stop()//关闭
    85   }
    86 }

    五.测试数据

    百度,博客园
    百度,Apache
    博客园,GitHub
    GitHub,百度
    GitHub,博客园
    GitHub,Apache
    Apache,博客园
    Apache,GitHub
    Apache,百度
    Apache,Apache

    六.结果

    <<<<<<<<<<<<<<<<<<<正在进行第1迭代计算,当前误差为:4>>>>>>>>>>>>>>>>>>>
    (Apache,0.2275)
    (GitHub,0.29833333333333334)
    (博客园,0.865)
    (百度,0.44)
    <<<<<<<<<<<<<<<<<<<正在进行第2迭代计算,当前误差为:1.544722222222222>>>>>>>>>>>>>>>>>>>
    (Apache,0.37631944444444443)
    (GitHub,0.921875)
    (博客园,0.37631944444444443)
    (百度,0.15631944444444446)
    <<<<<<<<<<<<<<<<<<<正在进行第3迭代计算,当前误差为:0.8594461805555556>>>>>>>>>>>>>>>>>>>
    (Apache,0.4526015625)
    (GitHub,0.42983940972222223)
    (博客园,0.4526015625)
    (百度,0.3711657986111111)
    <<<<<<<<<<<<<<<<<<<正在进行第4迭代计算,当前误差为:0.26803075086805556>>>>>>>>>>>>>>>>>>>
    (Apache,0.42071112919560183)
    (GitHub,0.51088916015625)
    (博客园,0.42071112919560183)
    (百度,0.2479656647858796)
    <<<<<<<<<<<<<<<<<<<正在进行第5迭代计算,当前误差为:0.1224163202582465>>>>>>>>>>>>>>>>>>>
    (Apache,0.3845384511990017)
    (GitHub,0.47700557477032696)
    (博客园,0.3845384511990017)
    (百度,0.26415304366500286)
    <<<<<<<<<<<<<<<<<<<正在进行第6迭代计算,当前误差为:0.07653532812499986>>>>>>>>>>>>>>>>>>>
    (Apache,0.3741310439556734)
    (GitHub,0.43857210439893934)
    (博客园,0.3741310439556734)
    (百度,0.24686600039804718)
    <<<<<<<<<<<<<<<<<<<正在进行第7迭代计算,当前误差为:0.06505502890625>>>>>>>>>>>>>>>>>>>
    (Apache,0.3536829932561168)
    (GitHub,0.427514234202903)
    (博客园,0.3536829932561168)
    (百度,0.23376494308694676)
    <<<<<<<<<<<<<<<<<<<正在进行第8迭代计算,当前误差为:0.05529677457031257>>>>>>>>>>>>>>>>>>>
    (Apache,0.34063676990303304)
    (GitHub,0.40578818033462405)
    (博客园,0.34063676990303304)
    (百度,0.22628666909108067)
    <<<<<<<<<<<<<<<<<<<正在进行第9迭代计算,当前误差为:0.04700225838476582>>>>>>>>>>>>>>>>>>>
    (Apache,0.32853046572958056)
    (GitHub,0.39192656802197257)
    (博客园,0.32853046572958056)
    (百度,0.2173586313658713)
    <<<<<<<<<<<<<<<<<<<正在进行第10迭代计算,当前误差为:0.0399519196270508>>>>>>>>>>>>>>>>>>>
    (Apache,0.31823600323759005)
    (GitHub,0.37906361983767933)
    (博客园,0.31823600323759005)
    (百度,0.21085858490709475)
    <<<<<<<<<<<<<<<<<<<正在进行第11迭代计算,当前误差为:0.03395913168299314>>>>>>>>>>>>>>>>>>>
    (Apache,0.3096414082275123)
    (GitHub,0.3681257534399394)
    (博客园,0.3096414082275123)
    (百度,0.20502650964199703)
    <<<<<<<<<<<<<<<<<<<正在进行第12迭代计算,当前误差为:0.028865261930544117>>>>>>>>>>>>>>>>>>>
    (Apache,0.30223736265417794)
    (GitHub,0.35899399624173184)
    (博客园,0.30223736265417794)
    (百度,0.2001010960563292)
    <<<<<<<<<<<<<<<<<<<正在进行第13迭代计算,当前误差为:0.024535472640962563>>>>>>>>>>>>>>>>>>>
    (Apache,0.29598337098977673)
    (GitHub,0.3511271978200641)
    (博客园,0.29598337098977673)
    (百度,0.19594040516583683)
    <<<<<<<<<<<<<<<<<<<正在进行第14迭代计算,当前误差为:0.020855151744818112>>>>>>>>>>>>>>>>>>>
    (Apache,0.2906571779131597)
    (GitHub,0.3444823316766378)
    (博客园,0.2906571779131597)
    (百度,0.19238250571767906)
    <<<<<<<<<<<<<<<<<<<正在进行第15迭代计算,当前误差为:0.017726878983095412>>>>>>>>>>>>>>>>>>>
    (Apache,0.28613054254494075)
    (GitHub,0.3388232515327322)
    (博客园,0.28613054254494075)
    (百度,0.18936797761492716)
    <<<<<<<<<<<<<<<<<<<正在进行第16迭代计算,当前误差为:0.015067847135631168>>>>>>>>>>>>>>>>>>>
    (Apache,0.2822840520447514)
    (GitHub,0.33401370145399956)
    (博客园,0.2822840520447514)
    (百度,0.18680266155840736)
    <<<<<<<<<<<<<<<<<<<正在进行第17迭代计算,当前误差为:0.012807670065286408>>>>>>>>>>>>>>>>>>>
    (Apache,0.27901370763379935)
    (GitHub,0.32992680529754836)
    (博客园,0.27901370763379935)
    (百度,0.1846225764714762)
    <<<<<<<<<<<<<<<<<<<正在进行第18迭代计算,当前误差为:0.010886519555493496>>>>>>>>>>>>>>>>>>>
    (Apache,0.2762342693735318)
    (GitHub,0.3264520643609118)
    (博客园,0.2762342693735318)
    (百度,0.1827696743731544)
    <<<<<<<<<<<<<<<<<<<正在进行第19迭代计算,当前误差为:0.009253541622169403>>>>>>>>>>>>>>>>>>>
    (Apache,0.27387164541939113)
    (GitHub,0.32349891120937757)
    (博客园,0.27387164541939113)
    (百度,0.18119453381080053)
    <<<<<<<<<<<<<<<<<<<正在进行第20迭代计算,当前误差为:0.007865510378844143>>>>>>>>>>>>>>>>>>>
    (Apache,0.2718634263638678)
    (GitHub,0.32098862325810307)
    (博客园,0.2718634263638678)
    (百度,0.17985574949427757)
    <<<<<<<<<<<<<<<<<<<正在进行第21迭代计算,当前误差为:0.0066856838220175074>>>>>>>>>>>>>>>>>>>
    (Apache,0.2701564482271857)
    (GitHub,0.31885489051160953)
    (博客园,0.2701564482271857)
    (百度,0.17871775469211776)
    <<<<<<<<<<<<<<<<<<<正在进行第22迭代计算,当前误差为:0.005682831248714881>>>>>>>>>>>>>>>>>>>
    (Apache,0.26870550997071635)
    (GitHub,0.3170412262413848)
    (博客园,0.26870550997071635)
    (百度,0.17775046422656632)
    <<<<<<<<<<<<<<<<<<<正在进行第23迭代计算,当前误差为:0.004830406561407652>>>>>>>>>>>>>>>>>>>
    (Apache,0.2674722156001269)
    (GitHub,0.31549960434388613)
    (博客园,0.2674722156001269)
    (百度,0.17692826830383623)
    <<<<<<<<<<<<<<<<<<<正在进行第24迭代计算,当前误差为:0.004105845577196454>>>>>>>>>>>>>>>>>>>
    (Apache,0.2664239144082584)
    (GitHub,0.31418922907513486)
    (博客园,0.2664239144082584)
    (百度,0.17622940037912804)
    <<<<<<<<<<<<<<<<<<<正在进行第25迭代计算,当前误差为:0.0034899687406169944>>>>>>>>>>>>>>>>>>>
    (Apache,0.2655328585441725)
    (GitHub,0.31307540905877457)
    (博客园,0.2655328585441725)
    (百度,0.1756353633830431)
    <<<<<<<<<<<<<<<<<<<正在进行第26迭代计算,当前误差为:0.002966473429524441>>>>>>>>>>>>>>>>>>>
    (Apache,0.26477546111174943)
    (GitHub,0.3121286622031833)
    (博客园,0.26477546111174943)
    (百度,0.17513043167395612)
    <<<<<<<<<<<<<<<<<<<正在进行第27迭代计算,当前误差为:0.002521502415095772>>>>>>>>>>>>>>>>>>>
    (Apache,0.26413167323858)
    (GitHub,0.3113239274312338)
    (博客园,0.26413167323858)
    (百度,0.1747012397771487)
    <<<<<<<<<<<<<<<<<<<正在进行第28迭代计算,当前误差为:0.0021432770528314327>>>>>>>>>>>>>>>>>>>
    (Apache,0.2635844535740027)
    (GitHub,0.31063990281599124)
    (博客园,0.2635844535740027)
    (百度,0.1743364266687145)
    <<<<<<<<<<<<<<<<<<<正在进行第29迭代计算,当前误差为:0.0018217854949066081>>>>>>>>>>>>>>>>>>>
    (Apache,0.26311931684987677)
    (GitHub,0.31005848192237784)
    (博客园,0.26311931684987677)
    (百度,0.1740263355156731)
    <<<<<<<<<<<<<<<<<<<正在进行第30迭代计算,当前误差为:0.0015485176706707127>>>>>>>>>>>>>>>>>>>
    (Apache,0.26272395063610027)
    (GitHub,0.30956427415299403)
    (博客园,0.26272395063610027)
    (百度,0.1737627580419392)
    <<<<<<<<<<<<<<<<<<<正在进行第31迭代计算,当前误差为:0.001316240020070053>>>>>>>>>>>>>>>>>>>
    (Apache,0.2623878893546771)
    (GitHub,0.30914419755085654)
    (博客园,0.2623878893546771)
    (百度,0.17353871718685296)
    <<<<<<<<<<<<<<<<<<<正在进行第32迭代计算,当前误差为:0.001118804017059577>>>>>>>>>>>>>>>>>>>
    (Apache,0.2621022372650241)
    (GitHub,0.3087871324393444)
    (博客园,0.2621022372650241)
    (百度,0.17334828246061157)
    <<<<<<<<<<<<<<<<<<<正在进行第33迭代计算,当前误差为:9.509834145005613E-4>>>>>>>>>>>>>>>>>>>
    (Apache,0.26185943298905845)
    (GitHub,0.3084836270940881)
    (博客园,0.26185943298905845)
    (百度,0.17318641294329856)
    <<<<<<<<<<<<<<<<<<<当前误差为:9.509834145005613E-4已小于0.001,迭代完成!>>>>>>>>>>>>>>>>>>>

    Process finished with exit code 0

  • 相关阅读:
    js 提升
    omnipay支付--支付宝支付
    laravel 配置sql日志
    laravel monlog配置
    php openssl相关加密解密 验签代码
    laravel validator提示信息中文化
    opendevops_codo项目研究
    Python学习笔记
    shell编程总结
    关于JeeSite开源软件
  • 原文地址:https://www.cnblogs.com/yszd/p/10920003.html
Copyright © 2011-2022 走看看