搜索引擎通过算法来确定网页的相关性,了解到,尽管统计关键词出现次数可以帮助找到查询的最相关页面,但这仍然是一个较弱的推荐系统。本文将探讨一些实践问题,以帮助更好地理解PageRank算法。将构建R包之间的依赖结构,并尝试使用PageRank算法解决一些有趣的问题。但在那之前,应该先复习一下R包的知识,以便更好地理解。
R是一种建立在许多不同包之上的语言。这些包含有用户准备好的函数,使能够更容易地进行任何类型的统计分析。这些包彼此依赖。例如,像随机森林这样的统计包依赖于许多包来帮助评估多个统计参数。在深入依赖结构之前,让学习一些R命令。
许多私营公司喜欢在他们自己的服务器上创建R提供的所有包的镜像。这个“miniCRAN”包帮助这些公司创建所需的包的子集。但为什么需要一个包来创建镜像呢?原因是这些包之间存在复杂的依赖结构。这些依赖关系告诉R在安装新包之前应该先安装哪个包。“miniCRAN”就像所有这些包的蓝图。
这是一个神奇函数,它将显示一个包的所有依赖关系。包之间有三种不同类型的依赖关系。让了解这三种:
让尝试一些包依赖结构:
library(miniCRAN)
pkgs <- "ggplot2"
pkgDep(pkgs, suggests=FALSE, enhances=FALSE, includeBasePkgs = TRUE)
[1] "ggplot2" "chron" "stats" "methods" "plyr" "digest" "grid" "gtable" "reshape2" "scales"
[11] "proto" "MASS" "grDevices" "graphics" "utils" "Rcpp" "stringr" "RColorBrewer" "dichromat" "munsell" "labeling" "colorspace"
从上述示例中,可以看到“ggplot2”包有22个导入依赖包和另外35个建议包。让尝试可视化这个依赖结构。以下是帮助实现这一点的代码:
plot(makeDepGraph(pkgs, includeBasePkgs=FALSE, suggests=FALSE, enhances=TRUE),
legendPosEdge = c(-1, 1), legendPosVertex = c(1, 1), vertex.size=20)
可以清楚地看到,“lattice”或“stringr”等包并不直接与ggplot2相关联,但在安装ggplot2之前应该安装它们。
以下是一些使用这些问题来更深入地了解R包的问题:
1. 构成R基础的包:
# 此代码的主要部分由Andrie de Vries编写
library(miniCRAN)
library(igraph)
library(magrittr)
# 使用最新的CRAN镜像来查找依赖关系
MRAN <- "http://mran.revolutionanalytics.com/snapshot/2015-04-01/"
pdb <- MRAN %>%
contrib.url(type = "source") %>%
available.packages(type="source", filters = NULL)
g <- pdb[, "Package"] %>%
makeDepGraph(availPkgs = pdb, suggests=FALSE, enhances=TRUE, includeBasePkgs = FALSE)
# 使用page.rank算法
pr <- g %>%
page.rank(directed = FALSE) %>%
use_series("vector") %>%
sort(decreasing = TRUE) %>%
as.matrix %>%
set_colnames("page.rank")
# 显示结果 ---------------------------------------------------------
head(pr, 10)
page.rank
MASS 0.020425142
Rcpp 0.018934424
Matrix 0.009553795
lattice 0.008853670
mvtnorm 0.008597332
ggplot2 0.008207035
survival 0.008022737
plyr 0.006900871
igraph 0.004725656
sp 0.004640548
从上面的表格中可以清楚地看到,最重要的包是“MASS”和“Rcpp”。显然,它们构成了R的骨干。
2. 2014年10月至2015年4月期间增加的包数量:
MRAN <- "http://mran.revolutionanalytics.com/snapshot/2014-10-01/"
pdb1 <- MRAN %>%
contrib.url(type = "source") %>%
available.packages(type="source", filters = NULL)
g1 <- pdb1[, "Package"] %>%
makeDepGraph(availPkgs = pdb, suggests=FALSE, enhances=TRUE, includeBasePkgs = FALSE)
pr1 <- g %>%
page.rank(directed = FALSE) %>%
use_series("vector") %>%
sort(decreasing = TRUE) %>%
as.matrix %>%
set_colnames("page.rank")
# 最后找到两个的大小:
nrow(pr) - nrow(pr1)
[1] 498
在这段时间内增加了498个包。
哇,这就像每个月增加了70个包!
3. 这对最关键的包的重要性有何影响?
在第1部分中,看到MASS作为最关键的包,在2015年4月的重要性为0.020425142。如果它与2014年10月较少的包数量成比例地上升,其重要性可以计算为:
~ 0.020425142 * nrow(pr)/nrow(pr1) = 0.02212809
现在,让找到它在2014年10月的实际重要性:
head(pr1, 1)
page.rank
MASS 0.020854737
因此,MASS的重要性并没有像它应该的那样因为包的数量增加而下降。这可能只是因为新包同样使用了这个包“MASS”,因此增加了它的重要性。
4. 最关键包的依赖关系是什么?
这是最简单的问题。已经知道可以显示一个包的所有依赖关系的函数。以下代码将帮助:
pkgs <- "MASS"
pkgDep(pkgs, suggests=FALSE, enhances=FALSE, includeBasePkgs = TRUE)
"MASS" "grDevices" "graphics" "stats" "utils"
pkgDep(pkgs, suggests=TRUE, enhances=FALSE, includeBasePkgs = TRUE)
"MASS" "grDevices" "graphics" "stats" "utils" "grid" "lattice" "splines" "nlme" "nnet" "survival"
PageRank在任何具有链接结构的重要性确定练习中都非常有用。类似的分析可以在Python上进行,以了解方便使用的顶级包下面的结构。这种分析也可以在社交网络上进行,以了解用户在社交网络上的影响力大小。
讨论结束时,让看看R中前10个包的网络结构:
Thinkpot:
能想到PageRank算法的更多用途吗?与分享在各个领域练习PageRank算法的有用链接。