Внедрение PageRank для исследований

Прочитав теорию алгоритма PageRank с этого сайта, я хотел бы поиграть с Это. Я пытаюсь реализовать это на Java. Я имею в виду, что я хотел бы поиграть с PageRank в деталях (например, присвоить разные веса и т.д.). Для этого мне нужно построить матрицу гиперссылок. Если у меня есть 1 миллион узлов, моя матрица гиперссылок будет иметь размер 1 миллион x 1 миллион, что вызывает это исключение:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at WebGraph.main(WebGraph.java:6)

Как я могу реализовать PageRank в Java, есть ли способ хранения матрицы гиперссылок?


person torayeff    schedule 04.11.2012    source источник
comment
Где вы уже смотрели? Вы нашли какие-либо реализации с закрытым исходным кодом? Вы не думали реализовать это самостоятельно? Есть ли у вас предпочтения в отношении языка?   -  person acattle    schedule 04.11.2012
comment
@acattle Я посмотрел на Юнга и WebLA. Я хотел бы сосредоточиться на теории, а не на реализации. Языковые предпочтения: любые.   -  person torayeff    schedule 04.11.2012
comment
Вы пытались увеличить размер кучи, чтобы избавиться от этого исключения?   -  person Dan W    schedule 12.11.2012
comment
@DanW Как я могу это сделать?   -  person torayeff    schedule 12.11.2012
comment
вам нужна библиотека, которая хороша для хранения разреженных матриц. У Matlab есть такая библиотека (я полагаю, на С++), которую вы могли бы позаимствовать, я полагаю, и связать ее в своем java-коде. Увеличение размера кучи — это всего лишь временное решение, если только вы не имеете дело с небольшими графами/матрицами. Возможно, используйте это в java introcs.cs.princeton.edu/java/44st /SparseMatrix.java.html   -  person Adrian    schedule 13.11.2012
comment
Голосование за закрытие слишком широкое.   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 10.09.2015


Ответы (7)


Это отличная статья, чтобы узнать о PageRank. Я реализовал Perl-версию из него здесь для использования с Textrank. Однако, если вы хотите просто узнать о PageRank и о том, как различные аспекты, обсуждаемые в статье, влияют на результаты (коэффициент демпфирования, прямой или неориентированный граф и т. д.), я бы рекомендовал провести эксперименты в R или Octave. Если вы хотите научиться эффективно его реализовывать, то лучше всего программировать его с нуля, как вы это делаете.

Большинство веб-графиков (или сетей) очень разрежены, что означает, что большинство записей в матричном представлении графика равны нулю. Распространенной структурой данных, используемой для представления разреженной матрицы, является хеш. -map, где нулевые значения не сохраняются. Например, если матрица была

1, 0, 0
0, 0, 2,
0, 3, 0

двухмерная хэш-карта будет хранить только значения для hm(0,0)=1, hm(1,2)=2 и hm(2,1)=3. Таким образом, в матрице размером 1 000 000 на 1 000 000 веб-графика я ожидал бы получить всего несколько миллионов значений быть ненулевым. Если каждая строка содержит в среднем только 5 ненулевых значений, хэш-карта будет использовать около 5*(8+8+8)*10^6 байтов ~ 115 МБ для ее хранения (8 для левого целочисленного индекса, 8 для правого целочисленного индекса). index и 8 для двойного значения). Квадратная матрица будет использовать 8*10^6*10^6 ~ 7 терабайт.

Реализация эффективного умножения разреженной матрицы на вектор в Java нетривиальна, и уже есть некоторые реализован, если вы не хотите уделять время этому аспекту алгоритма. Умножение разреженной матрицы — наиболее сложный для реализации аспект алгоритма ранжирования страниц, поэтому после этого все становится проще (и интереснее).

person Jeff Kubina    schedule 17.11.2012

Модуль Python networkx имеет хорошую реализацию рейтинга страниц. Он использует scipy/numpy для реализации матрицы. Приведенных ниже двух вопросов о stackoverflow должно быть достаточно, чтобы вы начали.

person greeness    schedule 12.11.2012

Несколько предложений:

  • Используйте python, а не Java: python — отличный язык прототипирования, в нем доступны разреженные матрицы (в scipy), а также много других полезных функций. Как отмечали другие, он также имеет реализацию рейтинга страниц.

  • Храните ваши данные не все в памяти: любой тип легковесной базы данных подойдет, например, sqlite, hibernate,...

  • Работайте с плитками данных: если есть большая матрица NxN, разбейте ее на маленькие плитки MxM, где M — часть N, которые помещаются в памяти. В сочетании с разреженными матрицами это позволяет работать с действительно большими N (от сотен миллионов до миллиардов, в зависимости от того, насколько разрежены данные).

person Alex I    schedule 16.11.2012

Как предложил Dan W, попробуйте увеличить размер кучи. Если вы запускаете приложение Java из командной строки, просто добавьте переключатель -Xmx с нужным размером кучи. Предположим, вы скомпилировали свой код Java в исполняемый файл JAR с именем pagerank.jar и хотите установить размер кучи равным 512 МБ, вы должны ввести следующую команду:

java -jar -Xmx512m pagerank.jar

EDIT: Но это работает, только если у вас не так много "страниц"... Массив 1 миллион x 1 миллион слишком велик, чтобы поместиться в вашу оперативную память (1 триллион раз * 64-битный двойной значение = 7,27595761 терабайт). Вы должны изменить свой алгоритм, чтобы загружать фрагменты данных с диска, манипулировать ими и сохранять их обратно на диск.

Для этой цели вы можете использовать графическую базу данных, такую ​​как Neo4j.

person das_weezul    schedule 12.11.2012
comment
У меня есть WebGraph.class, поэтому я запустил: java -Xmx2048m WebGraph, но все равно выдает OutOfMemoryError - person torayeff; 12.11.2012
comment
@torayeff: Смотрите мой отредактированный ответ. 1 миллион * 1 миллион узлов = 1 триллион ячеек. Если вы используете двойной массив (двойной, вероятно, 64-битный), это будет более 7 терабайт, что, вероятно, больше, чем может обработать ваша оперативная память. - person das_weezul; 12.11.2012

Вам не нужно хранить всю матрицу 1000000x1000000, потому что большинство элементов матрицы будут нулевыми. Вместо этого вы можете (например) сохранить список ненулевых элементов для каждой строки и написать свои матричные функции, чтобы использовать его напрямую, не расширяя его до полной матрицы.

Этот тип сжатого представления называется форматом разреженной матрицы, и большинство библиотек матриц позволяют создавать и работать с разреженными матрицами.

Одним из недостатков разреженных матриц является то, что умножение двух из них приведет к гораздо менее разреженной матрице. Однако алгоритм PageRank устроен так, что вам не нужно этого делать: матрица гиперссылок постоянна, а обновляется только вектор оценок.

person comingstorm    schedule 12.11.2012

PageRank выполняется Google с использованием структуры Pregel BSP (на самом деле просто ключевые слова).

Я вспомнил Apache Giraph (еще один Pregel), который включает в свой тестовый пакет версию PageRank.

Вот видео о Giraph: это введение, и в нем конкретно рассказывается об управлении PageRank.

Если это не работает:

В Java есть реализация Pregel под названием GoldenOrb.

Псевдокод для алгоритма PageRank находится здесь (на другой реализации Pregel).

Вам придется ознакомиться с BSP и PageRank, чтобы справиться с объемом данных, которые у вас есть.

person Tom    schedule 12.11.2012

Поскольку матрица разрежена, вы можете реализовать уменьшение размерности, например svd, pca, mds или Lsi, включающее svd. Существует библиотека для реализации такого рода процессов, которая называется Jama. Вы можете найти его здесь

person Lefteris Bab    schedule 16.11.2012