从this site阅读PageRank算法理论后,我想玩它。 我试图用Java实现它。我的意思是我想详细使用PageRank(比如赋予不同的权重等)。为此,我需要构建超链接矩阵。如果我有100万个节点,那么我的超链接矩阵将是100万x 100万大小,这导致了这个例外:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at WebGraph.main(WebGraph.java:6)
如何在Java中实现PageRank,有没有办法存储超链接矩阵?
答案 0 :(得分:8)
这是一篇了解pagerank的好文章。我从here实现了Perl版本,以便与Textrank一起使用。但是,如果您只想了解pagerank以及文章中讨论的各个方面如何影响结果(阻尼系数,直接或无向图等),我建议您在R或{{3}中运行实验}}。如果您想学习如何有效地实现它,那么最好从头开始编程,就像您一样。
大多数网络图(或网络)非常Octave,这意味着图表矩阵表示中的大多数条目都为零。用于表示稀疏矩阵的公共数据结构是sparse,其中不存储零值。例如,如果矩阵是
1, 0, 0
0, 0, 2,
0, 3, 0
二维散列映射仅存储hm(0,0)= 1,hm(1,2)= 2和hm(2,1)= 3的值。因此,在hash-map的1,000,000 x 1,000,000矩阵中,我预计只有几百万个值不为零。如果每行平均只有5个非零值,则哈希映射将使用大约5 *(8 + 8 + 8)* 10 ^ 6字节~115mb来存储它(8表示左int索引,8表示右int index,和double值为8)。方阵将使用8 * 10 ^ 6 * 10 ^ 6~7太字节。
在Java中实现有效的稀疏矩阵向量乘法并非易事,如果您不想将时间用于算法的这一方面,则有一些已经web graph。稀疏矩阵乘法是实现Pagerank算法最困难的方面,因此之后它变得更容易(也更有趣)。
答案 1 :(得分:4)
Python networkx
模块有一个很好的pagerank实现。它使用scipy / numpy进行矩阵实现。有关stackoverflow的以下两个问题应该足以让您入门。
答案 2 :(得分:2)
一些建议:
使用python,而不是Java:python是一种优秀的原型语言,并且有可用的稀疏矩阵(scipy)以及许多其他好东西。正如其他人所指出的那样,它也有一个pagerank实现。
将您的数据存储在内存中:任何类型的轻量级数据库都可以,例如sqlite,hibernate,...
处理数据的切片:如果有一个大矩阵NxN,将其分解为小块MxM,其中M是N的一小部分,适合内存。结合稀疏矩阵,您可以使用非常大的N(数亿到数十亿,取决于数据的稀疏程度)。
答案 3 :(得分:0)
正如 Dan W 建议的那样,尝试增加堆大小。如果从命令行运行Java应用程序,只需添加具有所需堆大小的开关-Xmx
即可。假设您将Java代码编译为名为pagerank.jar
的可运行JAR文件,并且您希望将堆大小设置为512 MB,您将发出以下命令:
java -jar -Xmx512m pagerank.jar
修改强> 但这只有在没有那么多“页面”的情况下才有效......一百万x一百万个阵列太大而无法放入你的RAM(1万亿次* 64位双值= 7.27595761太字节)。您应该更改算法以从磁盘加载数据块,对其进行操作并将其存储回磁盘。
您可以使用Neo4j之类的图表数据库来实现此目的。
答案 4 :(得分:0)
PageRank由Google使用'Pregel'BSP(实际上只是关键字)框架执行。
我记得Apache Giraph(另一个Pregel),其基准包中包含一个PageRank版本。
Here's a video about Giraph:这是一个介绍,它专门讨论了如何处理PageRank。
如果不起作用:
在Java中,有一个名为GoldenOrb的Pregel实现。
PageRank算法的伪代码是here(在Pregel的不同实现上)。
您必须阅读BSP和PageRank来处理您拥有的数据大小。
答案 5 :(得分:0)
您不必存储整个1000000x1000000矩阵,因为大多数矩阵条目将为零。相反,您可以(例如)为每一行存储非零条目列表,并编写矩阵函数以直接使用它,而不将其扩展为完整矩阵。
这种压缩表示称为sparse matrix格式,大多数矩阵库都可以选择构建和使用稀疏矩阵。
稀疏矩阵的一个缺点是,将它们中的两个相乘将导致矩阵更稀疏。但是,PageRank算法的设计使您无需这样做:超链接矩阵是常量,只更新得分向量。
答案 6 :(得分:0)
因为矩阵稀疏,你可以实现降维,如svd,pca,mds或包含svd的Lsi。有一个库可以实现这种称为Jama的过程。你可以找到它here