【问题标题】:page rank algo implementation in RR中的页面排名算法实现
【发布时间】:2013-11-26 01:26:12
【问题描述】:

我正在尝试使用以下步骤在 R 中实现页面排名算法:

  1. 加载一个示例图,例如:

    0 1
    0 2
    0 3
    1 2
    1 5
    2 0
    2 4
    3 1
    3 0
    3 4
    4 1
    4 5
    5 2
    5 3
    
  2. 从此图创建邻接矩阵

  3. 创建马尔可夫链(转移矩阵)
  4. 找到平稳分布并对其进行归一化

以下是实现所有这些步骤的代码:

g = read.graph(x)

a = get.adjacency(g)

markov = a / rowSums(a)

e = eigen(t(markov))

v <- e$vec[,1]

normalized <- v / sum(v)

当我将归一化对象的向量与 page.rank(g) 为这个特定图形生成的向量进行比较时,它们几乎相同,但差异很小。但是,当我在此图上尝试时:

    0 1
    0 2
    0 3
    1 2
    1 5
    2 0
    2 4
    3 1
    3 0
    3 4
    4 1
    4 5
    5 2
    5 3
    6 1
    6 2
    6 5
    6 0
    7 3
    7 4
    7 6
    7 7
    7 1
    8 2
    8 5
    9 8 
    9 7
    9 1 
    9 5
    10 2 
    10 3
    10 9

差别很大!

任何人对此都有解释,或者 R 中该算法的替代实现。

【问题讨论】:

    标签: r igraph pagerank


    【解决方案1】:

    原因是阻尼参数。

    您的代码根本没有使用阻尼。贝塔=0。 page.rank 默认使用 beta=0.85。

    如果您使用以下使用阻尼(beta 变量)的代码,您将获得与 page.rank 相同的结果。 或者您可以使用 M=beta*M+(1-beta)*U 之类的内容修改代码并应用特征向量技术。 (如果某列等于 0 向量,那么在添加阻尼效果之前,您必须在此列中使用 1/n 修改矩阵)。

    我使用您的第一个示例展示了三种不同的方法来获得相同的确切结果。没有细微差别。

    您使用特征向量、page.rank 函数的方式以及使用矩阵迭代的不同方式。

    代码如下:

    g <- graph(c(
      1, 2, 1, 3, 1, 4, 
      2, 3, 2, 6, 3, 1, 
      3, 5, 4, 2, 4, 1, 
      4, 5, 5, 2, 5, 6, 
      6, 3, 6, 4), 
                directed=TRUE)
    
    M = get.adjacency(g, sparse = FALSE)
    M = t(M / rowSums(M))
    n = nrow(M)
    
    U = matrix(data=rep(1/n, n^2), nrow=n, ncol=n)
    beta=0.85
    A = beta*M+(1-beta)*U
    e = eigen(A)
    v <- e$vec[,1]
    v <- as.numeric(v) / sum(as.numeric(v))
    v
    
    page.rank(g)$vector
    
    library(expm)
    n = nrow(M)
    U = matrix(data=rep(1/n, n^2), nrow=n, ncol=n)
    beta=0.85
    A = beta*M+(1-beta)*U
    r = matrix(data=rep(1/n, n), nrow=n, ncol=1)
    t(A%^%100 %*% r)
    

    【讨论】:

    • 我认为他使用阻尼 = 1,而不是阻尼 = 0
    【解决方案2】:

    @Roc 说您使用 0 的阻尼系数是不正确的,反之亦然:您使用的阻尼系数为 1。

    运行以下代码时,三种不同的方法(igraph、将矩阵提升为 n't power 和特征向量)得到相同的结果:

    library(igraph)
    library(expm)
    
    set.seed(1415)
    n <- 10
    g <- sample_gnp(n, p = 1/4, directed = TRUE) # create random graph
    df <- data.frame(pr = page_rank(g, damping = 1)$vector)
    
    r <- c(1, rep(0, (n-1)))
    adj_m <- t(as_adjacency_matrix(g, sparse = FALSE))
    adj_m_mod <- prop.table(adj_m, 2)
    
    lr <- eigen(adj_m_mod)$vectors[ , 1]
    lr <- Re(lr/sum(lr))
    
    matrix(lr, ncol = 1)
    ##             [,1]
    ##  [1,] 0.27663551
    ##  [2,] 0.02429907
    ##  [3,] 0.08878505
    ##  [4,] 0.06915888
    ##  [5,] 0.14579439
    ##  [6,] 0.10654206
    ##  [7,] 0.06915888
    ##  [8,] 0.07289720
    ##  [9,] 0.05327103
    ## [10,] 0.09345794
    adj_m_mod %^% 100 %*% r
    ##             [,1]
    ##  [1,] 0.27663574
    ##  [2,] 0.02429905
    ##  [3,] 0.08878509
    ##  [4,] 0.06915881
    ##  [5,] 0.14579434
    ##  [6,] 0.10654199
    ##  [7,] 0.06915881
    ##  [8,] 0.07289723
    ##  [9,] 0.05327107
    ## [10,] 0.09345787
    df
    ##            pr
    ## 1  0.27663551
    ## 2  0.02429907
    ## 3  0.08878505
    ## 4  0.06915888
    ## 5  0.14579439
    ## 6  0.10654206
    ## 7  0.06915888
    ## 8  0.07289720
    ## 9  0.05327103
    ## 10 0.09345794
    

    另外一点:您必须始终小心邻接矩阵的定义方式,即传入和传出链接是否在行或列中。要将一种形式转换为另一种形式,请使用转置函数t()

    编辑
    我在 R 中发表了一篇关于 pagerank 算法的博文:
    http://blog.ephorie.de/googles-eigenvector-or-how-a-random-surfer-finds-the-most-relevant-webpages

    【讨论】:

      猜你喜欢
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多