我正在尝试使用以下步骤在R中实现页面排名算法:
加载一个样本图,例如:
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
从此图表中创建邻接矩阵
以下是实现所有这些步骤的代码:
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 :(得分:5)
原因是阻尼参数。
您的代码根本没有使用阻尼。的β= 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)
@Roc说明你使用阻尼因子0是不正确的,反之亦然:你使用阻尼因子为1。
运行以下代码时,您可以获得三种不同方法的相同结果(igraph,将矩阵提升为n&#39; t幂和特征向量):
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()
。