页面排序算法在R中的实现



我正在尝试使用以下步骤在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.中有该算法的替代实现。

原因是阻尼参数。

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

如果您使用以下代码,其中使用阻尼(贝塔变量),您将得到与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)

@Roc说你使用的阻尼因子为0是不正确的,反之亦然:你使用的是阻尼因子1。

当运行以下代码时,对于三种不同的方法(igraph、将矩阵提升为幂和特征向量),您会得到相同的结果:

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

相关内容

  • 没有找到相关文章

最新更新