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

Голоса, которые имеют разный вес

Пусть каждая веб-страница является вершиной, а гиперссылка — ориентированным ребром. Уже здесь возникает отличие от школьного голосования. Страница AA, на которую ссылаются сто никому не известных каталогов, не обязательно важнее страницы BB, на которую ведёт одна ссылка с главной страницы университета. Голос сам имеет вес, а этот вес ещё только предстоит найти.

Формально мы хотим числа πi0\pi_i\ge 0, удовлетворяющие рекурсивному условию: важность страницы складывается из важностей тех, кто на неё ссылается, поделённых на число их исходящих ссылок,

πj=ijπidi,\pi_j=\sum_{i\to j}\frac{\pi_i}{d_i},

где did_i — исходящая степень вершины ii. Определение выглядит порочным кругом: чтобы узнать πj\pi_j, надо знать πi\pi_i. Весь урок — рассказ о том, почему этот круг не порочен, а разрешим, и что именно превращает его в корректную задачу о собственном векторе.

Матрица переходов и один шаг читателя

Если из вершины ii выходит did_i ссылок, простейший случайный читатель выбирает каждую с вероятностью 1/di1/d_i. Переходы задаёт строко-стохастическая матрица

Pij={1/di,если ij,0,иначе,jPij=1.P_{ij}= \begin{cases} 1/d_i,&\text{если }i\to j,\\ 0,&\text{иначе}, \end{cases} \qquad \sum_j P_{ij}=1 .

Вектор-строка ptp_t хранит вероятности положения после tt кликов, поэтому

pt+1=ptP,pt=p0Pt.p_{t+1}=p_tP,\qquad p_t=p_0P^{\,t}.

Эта формула связывает тему с цепями Маркова, а способ многократно умножать вектор на матрицу — со степенным методом для собственных векторов. Никаких меток «хорошая страница» алгоритм не получает. Ранг рождается из геометрии графа и правила движения.

Возьмём три страницы: AA ссылается на BB и CC, BB — только на CC, CC — только на AA. Тогда

P=(01212001100),P=\begin{pmatrix} 0&\tfrac12&\tfrac12\\ 0&0&1\\ 1&0&0 \end{pmatrix},

и из p0=(1,0,0)p_0=(1,0,0) три шага дают

p1=(0,12,12),p2=(12,0,12),p3=(12,14,14).p_1=\left(0,\tfrac12,\tfrac12\right),\quad p_2=\left(\tfrac12,0,\tfrac12\right),\quad p_3=\left(\tfrac12,\tfrac14,\tfrac14\right).

Никакой мистики: масса просто растекается по стрелкам, деля себя поровну на каждой развилке.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Три панели: ориентированный граф из вершин A, B, C; матрица переходов с дробями 1/2 и единицами; столбцы вероятностей после нуля, одного и двух шагов и красные точки предельного распределения 0.4, 0.2, 0.4
Рис. 65.1. Один граф — три языка: рёбра, матрица, поток вероятности

Слева — три страницы и направления ссылок. В центре та же система записана матрицей PP: строка «откуда», столбец «куда», сумма каждой строки равна единице. Справа — первые шаги потока и красными точками предел π=(0,4;0,2;0,4)\pi=(0{,}4;\,0{,}2;\,0{,}4). Одна и та же модель на трёх языках: рёбра, числа, вероятность.

Неподвижное распределение

Если после долгого движения распределение перестаёт заметно меняться, его предел π\pi удовлетворяет

π=πP,πi0,iπi=1.\pi=\pi P,\qquad \pi_i\ge 0,\qquad \sum_i\pi_i=1.

Это левый собственный вектор матрицы PP для собственного числа 11. Компонента πi\pi_i имеет ясный частотный смысл: доля времени, которую длинная траектория проводит на странице ii. В отличие от отдельной прогулки, стационарное распределение описывает весь поток сразу.

Для нашего примера баланс потоков даёт систему

πA=πC,πB=12πA,πC=12πA+πB,\pi_A=\pi_C,\qquad \pi_B=\tfrac12\pi_A,\qquad \pi_C=\tfrac12\pi_A+\pi_B,

и после нормировки πA+πB+πC=1\pi_A+\pi_B+\pi_C=1 получаем

(πA,πB,πC)=(0,4; 0,2; 0,4).(\pi_A,\pi_B,\pi_C)=(0{,}4;\ 0{,}2;\ 0{,}4).

Входящая степень у CC равна двум, а у AA — единице, но один из входов CC несёт только половину потока. Поэтому просто считать ссылки недостаточно — тезис, к которому мы вернёмся уже на настоящих данных.

Это редкий случай, когда инженерная метафора и математический объект совпадают буквально: «становится скучно» — это телепортация, «нажимает на ссылки» — это матрица PP, а «доля времени на странице» — это π\pi.

Тупики: куда утекает вероятность

Реальный граф неудобнее учебного. У страницы без исходящих ссылок строка матрицы состоит из нулей, и суммарная вероятность перестаёт сохраняться. Возьмём цепочку ABCA\to B\to C, где у CC выходов нет, и стартуем с равномерного p0=(1/3,1/3,1/3)p_0=(1/3,1/3,1/3). Суммарная масса ipt,i\sum_i p_{t,i} падает по шагам как

1  23  13  0.1\ \longrightarrow\ \tfrac23\ \longrightarrow\ \tfrac13\ \longrightarrow\ 0 .

Через три шага «читателей» не остаётся вовсе: они провалились в тупик и исчезли из модели. Формально PP перестала быть стохастической — это субстохастическая матрица, и единственный её неотрицательный предел нулевой.

Лечение прямое: нулевую строку заменяют на распределение vv — равномерное или заданное. Читатель, попавший в тупик, просто начинает заново. В нашем реальном графе такая починка понадобится 2424 раза — ровно столько там вершин без исходящих рёбер.

Ловушки: когда ответ перестаёт быть единственным

Вторая неприятность тоньше. Группа страниц может ссылаться только друг на друга. Попав внутрь такого замкнутого множества, случайный читатель больше не выйдет: множество поглощающее. Тогда предел зависит от начальной точки, а несколько стационарных распределений конкурируют между собой.

Возьмём шесть вершин: ABCA\to B\to C, CAC\to A и CDC\to D, а внутри — цикл DEFDD\to E\to F\to D. Стартуя с равномерного распределения и не применяя никакой телепортации, после четырёхсот шагов мы получаем

πD+πE+πF=1,000,\pi_D+\pi_E+\pi_F=1{,}000,

то есть весь поток оказался в ловушке, а вершины A,B,CA,B,C обнулились. Спам-фермы начала двухтысячных эксплуатировали именно это: достаточно построить плотный клубок страниц, ссылающихся только внутрь, чтобы накопить в нём весь ранг.

Телепортация чинит обе болезни сразу

PageRank смешивает следование ссылкам со случайным перезапуском:

G=αP+(1α)1v,0<α<1,G=\alpha P+(1-\alpha)\,\mathbf 1v^\top,\qquad 0<\alpha<1,

то есть

pt+1=αptP+(1α)v.p_{t+1}=\alpha\,p_tP+(1-\alpha)\,v .

С вероятностью α\alpha читатель нажимает ссылку, а с вероятностью 1α1-\alpha выбирает новую страницу по вектору интересов vv. При положительных компонентах vv из любой вершины можно попасть в любую другую за один прыжок, и матрица GG становится строго положительной.

На графе с ловушкой при α=0,85\alpha=0{,}85 ранг перестаёт быть вырожденным: в ловушке остаётся 0,7630{,}763 вероятности вместо всей, а вершины снаружи получают πA=0,0644\pi_A=0{,}0644, πB=0,0798\pi_B=0{,}0798, πC=0,0928\pi_C=0{,}0928; внутри ловушки πD=0,2689\pi_D=0{,}2689, πE=0,2536\pi_E=0{,}2536, πF=0,2405\pi_F=0{,}2405. Заметьте: перекос не исчез — он стал конечным. Телепортация не объявляет ловушку несуществующей, она лишь мешает ей забрать всё.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Слева граф из шести вершин, где D, E, F образуют замкнутый цикл, размер вершин пропорционален рангу; справа столбчатая диаграмма: без телепортации вся масса в D, E, F, при альфа 0.85 масса перераспределена
Рис. 65.2. Ловушка и её разрушение телепортацией

Слева: вершины D,E,FD,E,F образуют ловушку, войти в неё можно через CC, выйти — нельзя. Справа серые столбцы — предел без телепортации (α=1\alpha=1): ровно 1,0001{,}000 массы внутри ловушки и ноль снаружи. Зелёные столбцы — PageRank при α=0,85\alpha=0{,}85: в ловушке остаётся 0,7630{,}763, остальное возвращается в A,B,CA,B,C через случайные прыжки.

Сходимость: почему всё держится на альфе

Пусть pp и qq — два распределения. Один шаг PageRank не увеличивает расстояние между ними больше чем в α\alpha раз:

(αpP+(1α)v)(αqP+(1α)v)1=α(pq)P1αpq1.\lVert\bigl(\alpha pP+(1-\alpha)v\bigr)-\bigl(\alpha qP+(1-\alpha)v\bigr)\rVert_1 =\alpha\lVert (p-q)P\rVert_1\le\alpha\lVert p-q\rVert_1 .

Отображение сжимающее с коэффициентом α\alpha, значит по теореме о неподвижной точке решение единственно, а ошибка убывает геометрически:

ptπ12αt.\lVert p_t-\pi\rVert_1\le 2\alpha^{\,t}.

Чтобы получить точность ε\varepsilon, достаточно

t  ln(2/ε)ln(1/α)t\ \ge\ \frac{\ln(2/\varepsilon)}{\ln(1/\alpha)}

итераций. Это и есть весь секрет масштабируемости: число шагов не зависит от размера графа — только от α\alpha и требуемой точности.

На нашем реальном графе счёт до порога pt+1pt1<1012\lVert p_{t+1}-p_t\rVert_1<10^{-12} занимает 4040 итераций при α=0,70\alpha=0{,}70, 5757 при 0,850{,}85 и 7575 при 0,950{,}95. Практика оказалась лучше теории: у матрицы GG второе по модулю собственное число равно 0,63140{,}6314, а не 0,850{,}85 — граф хорошо перемешан, и реальная скорость определяется именно этой величиной, ptπλ2t\lVert p_t-\pi\rVert\sim|\lambda_2|^{\,t}.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Полулогарифмический график невязки L1 по итерациям для альфа 0.70, 0.85 и 0.95: прямые падающие линии, рядом штриховые теоретические оценки два альфа в степени t, горизонтальный порог десять в минус двенадцатой
Рис. 65.3. Скорость сходимости задаёт альфа: ошибка падает геометрически

Сплошные линии — реальная невязка pt+1pt1\lVert p_{t+1}-p_t\rVert_1 на графе из 383383 фильмов, штриховые — теоретическая оценка 2αt2\alpha^{\,t}. Прямая на полулогарифмической бумаге означает геометрическое убывание. Порог 101210^{-12} достигается за 4040, 5757 и 7575 итераций; наклон реальных кривых круче теоретического, потому что λ2=0,6314<0,85|\lambda_2|=0{,}6314<0{,}85.

Как это считают на миллиарде страниц

Для миллиарда страниц нельзя хранить плотную матрицу 109×10910^9\times10^9: это 101810^{18} чисел. Но веб-граф разрежен, каждая страница содержит лишь небольшое число ссылок. На одной итерации достаточно пройти по списку рёбер и распределить массу pip_i между соседями:

qj += αpidi  для каждого ребра ij,q += (1α)v.q_j\ \mathrel{+}=\ \alpha\frac{p_i}{d_i}\ \ \text{для каждого ребра } i\to j, \qquad q\ \mathrel{+}=\ (1-\alpha)v .

Цена шага близка к O(E)O(|E|), память — O(V+E)O(|V|+|E|). В нашем учебном графе плотная матрица заняла бы 146689146\,689 клеток, а список рёбер — всего 35823582 записи: в 4141 раз меньше. На веб-масштабе выигрыш становится вопросом принципиальной возможности счёта, а не удобства; та же логика цены матричных операций разбиралась в уроке о стоимости умножения матриц.

Живой граф: фильмы вместо страниц

Настоящего снимка веба у нас под рукой нет, зато есть реальные данные о поведении людей: MovieLens 100K — сто тысяч оценок, поставленных 943943 зрителями. Построим из них честный ориентированный граф. Скажем, что фильм ii ссылается на фильм jj, если из тех, кто поставил ii оценку не ниже четырёх, не менее 60%60\% поставили не ниже четырёх и фильму jj:

P(j нравитсяi нравится)  0,6.\mathbb P(j\ \text{нравится}\mid i\ \text{нравится})\ \ge\ 0{,}6 .

Это условная вероятность, и она несимметрична: из того, что почти все поклонники нишевого фильма любят блокбастер, не следует обратное. Именно поэтому получается ориентированный граф, а не сеть похожести. Взяв фильмы, набравшие хотя бы 4545 поклонников, получаем 383383 вершины и 35823582 ребра: средняя исходящая степень 9,359{,}35, максимальная входящая — 332332, и 2424 вершины оказались тупиками, у которых ни один другой фильм не собирает шестидесяти процентов их аудитории.

Ранг против входящей степени

Теперь главный эксперимент урока. Считаем PageRank при α=0,85\alpha=0{,}85 и равномерном vv, а рядом — обычный подсчёт входящих ссылок. По всему списку ранговая корреляция Спирмена (со связными рангами: входящих степеней с совпадающими значениями много) высока, ρ=0,996\rho=0{,}996: в целом популярное остаётся популярным. Но интересна вершина списка, и там согласия нет.

Первое место по числу входящих ссылок занимает Star Wars (1977) с 332332 входами. Первое место по PageRank занимает Return of the Jedi (1983), у которого входов почти вдвое меньше — 177177, зато

πJedi=0,2381>πStar Wars=0,2169.\pi_{\text{Jedi}}=0{,}2381>\pi_{\text{Star Wars}}=0{,}2169 .

Почему? Смотрим на исходящие рёбра. У Star Wars исходящая степень равна единице: единственный фильм, который любят шестьдесят процентов её поклонников, — это как раз Return of the Jedi. Значит вся полученная масса

απStar Wars11=0,850,2169=0,1844\alpha\,\pi_{\text{Star Wars}}\cdot\frac{1}{1}=0{,}85\cdot0{,}2169=0{,}1844

уходит одному адресату. А сам Jedi имеет две исходящие ссылки и делит свой поток пополам, по 0,50{,}5 каждому. Побеждает не тот, у кого больше входов, а тот, кому достаётся более концентрированный поток от сильных соседей.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Диаграмма рассеяния: по горизонтали логарифм единицы плюс входящая степень, по вертикали логарифм ранга; подписаны Return of the Jedi с входом 177 и рангом 0.2381, Star Wars с входом 332 и меньшим рангом, Braveheart с входом 58 и рангом 0.0020
Рис. 65.4. Ранг растёт со степенью, но не определяется ею

Каждая точка — фильм. По горизонтали log10(1+diвх)\log_{10}(1+d_i^{\text{вх}}), по вертикали log10πi\log_{10}\pi_i. Облако вытянуто — связь есть; но подписанные точки показывают, что порядок на вершине определяется не степенью. Штриховая линия — равномерный уровень 1/383=0,002611/383=0{,}00261. У Braveheart (1995) 5858 входящих ссылок и ранг всего 0,00200{,}0020: его поклонники расходятся по разным кластерам, и входящий поток приходит от слабых вершин.

Разброс рангов огромен: от πmin=0,00043\pi_{\min}=0{,}00043 до πmax=0,23809\pi_{\max}=0{,}23809, отношение 554,4554{,}4. Список из десяти лучших по степени и десяти лучших по PageRank совпадает на девяти позициях из десяти — и всё же расходится там, где решение важнее всего, на первом месте. Именно поэтому спор «зачем считать собственный вектор, если есть счётчик ссылок» решается не корреляцией по всей выборке, а поведением верхушки.

Персонализация и её линейность

Вектор vv не обязан быть равномерным. Сосредоточим всю телепортацию на 4141 фильме с жанровой меткой Sci-Fi:

vi=1{iSci-Fi}41.v_i=\frac{\mathbb 1\{i\in \text{Sci-Fi}\}}{41}.

Первая пятёрка меняет не только числа, но и состав. Return of the Jedi поднимается с 0,23810{,}2381 до 0,26130{,}2613, Star Wars — с 0,21690{,}2169 до 0,22990{,}2299. Коэффициент Жаккара между старой и новой первой десяткой равен 0,6670{,}667: два фильма — Contact (1997) и Back to the Future (1985) — входят в неё впервые.

Тонкий эффект: выигрывают и фильмы, которых нет среди источников телепортации. Мультфильм Toy Story (1995), не помеченный как фантастика, прибавляет 16,4%16{,}4\% ранга (с 0,00300{,}0030 до 0,00350{,}0035) — просто потому, что на него ведут рёбра из «фантастического» кластера. Поток идёт по рёбрам, а не по жанровым ярлыкам.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Парные точки для девяти фильмов: синяя точка равномерного PageRank и фиолетовая точка персонализированного, соединённые линией; у фантастики сдвиг вправо
Рис. 65.5. Персонализация двигает не только числа, но и порядок

Для фильмов из верхушки обоих списков показаны два ранга: синий — при равномерной телепортации, фиолетовый — при телепортации только в фантастику. Длина отрезка — величина сдвига. Часть фильмов растёт, часть падает; сумма всех рангов в обоих случаях равна единице, поэтому чей-то выигрыш всегда чей-то проигрыш.

У персонализации есть замечательное алгебраическое свойство. Отображение vπ(v)v\mapsto\pi(v) линейно: решая

π=απP+(1α)vπ=(1α)v(IαP)1,\pi=\alpha\pi P+(1-\alpha)v \quad\Longleftrightarrow\quad \pi=(1-\alpha)\,v\,(I-\alpha P)^{-1},

видим, что π\pi линейно зависит от vv. Значит для смеси

v=λv(1)+(1λ)v(2)v=\lambda v^{(1)}+(1-\lambda)v^{(2)}

выполняется

π(v)=λπ(v(1))+(1λ)π(v(2)).\pi(v)=\lambda\,\pi(v^{(1)})+(1-\lambda)\,\pi(v^{(2)}).

Мы проверили это численно: для λ=1/2\lambda=1/2 максимальное расхождение между пересчитанным рангом и полусуммой двух рангов составило 1,010131{,}0\cdot10^{-13}, то есть чистая ошибка округления. Практическое следствие огромно: можно заранее посчитать несколько тематических векторов и мгновенно комбинировать их под конкретного пользователя, не запуская степенной метод заново.

Чувствительность: насколько устойчив рейтинг

Рейтинг, который переворачивается от смены одного параметра, нельзя подавать как объективную шкалу. Проверим устойчивость первой десятки по α\alpha. Коэффициент Жаккара с эталонной десяткой при α=0,85\alpha=0{,}85 равен 1,0001{,}000 для всех α\alpha от 0,600{,}60 до 0,950{,}95 и падает до 0,8180{,}818 на краях, при α=0,50\alpha=0{,}50 и α=0,99\alpha=0{,}99. Цена итераций при этом растёт монотонно: от 2727 шагов при α=0,50\alpha=0{,}50 до 8585 при α=0,99\alpha=0{,}99.

α больше веса ссылкам,  медленнее сходимость,  сильнее влияние ловушек.\alpha\ \uparrow\quad\Longrightarrow\quad \text{больше веса ссылкам},\ \ \text{медленнее сходимость},\ \ \text{сильнее влияние ловушек}.
Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Слева график коэффициента Жаккара первой десятки по альфа: единица в середине диапазона и снижение до 0.818 на краях; справа число итераций растёт с 27 до 85
Рис. 65.6. Один параметр управляет и смыслом, и стоимостью

Слева: совпадение первой десятки с эталоном при α=0,85\alpha=0{,}85. Внутри диапазона 0,600{,}600,950{,}95 верхушка не меняется вовсе, у краёв теряет две позиции. Справа: число итераций до 101210^{-12} растёт от 2727 до 8585. Устойчивость и цена тянут α\alpha в разные стороны, и выбирать приходится осознанно.

Такой же анализ полезно проводить по данным, а не только по параметру: удалить одно ребро у лидера, добавить ссылку от середняка к аутсайдеру, превратить страницу в тупик — и посмотреть на

Δi=πi(new)πi(0)\Delta_i=\pi_i^{(\text{new})}-\pi_i^{(0)}

и на перестановки в первой пятёрке. Логика та же, что и в разговоре о случайных отклонениях выборочных оценок: прежде чем объявлять разницу содержательной, надо понять, какие возмущения её создают.

Русская линия: Романовский и теория цепей

Язык, на котором записан PageRank, создан задолго до веба. Андрей Андреевич Марков в начале XX века ввёл цепи зависимых испытаний и в 1913 году пересчитал чередование гласных и согласных в «Евгении Онегине», доказывая, что закон больших чисел не требует независимости.

Систематическую же теорию конечных цепей построил Владимир Иванович Романовский (1879–1954), основатель ташкентской математической школы. Его монография «Дискретные цепи Маркова» (1949) — первая в мире книга, целиком посвящённая этому предмету; в ней цепи изучаются именно матричным, спектральным способом: классификация состояний на существенные и несущественные, разложение матрицы переходов на эргодические классы, поведение PtP^{\,t} через характеристические числа. Всё, что нам понадобилось сегодня — разложимость графа, единственность π\pi, скорость забывания старта через λ2|\lambda_2|, — это словарь Романовского. Разница лишь в том, что он изучал цепи с десятками состояний, а мы применяем те же теоремы к графам с миллиардом вершин.

Лаборатория: поток по живому графу

Случайный читатель, ловушка и стационарное распределение

Загружается живая иллюстрация…

Сначала выберите граф «ловушка», установите α=0,99\alpha=0{,}99 и запустите прогулку. Серые столбцы — доля времени, которую читатель провёл в вершине; красные точки — точный вектор π\pi. Вы увидите, как почти вся масса уходит в D,E,FD,E,F. Затем верните α=0,85\alpha=0{,}85 и проследите, как частоты сходятся к новым точкам: это закон больших чисел в действии, только для зависимых испытаний.

Дальше переключите граф на «тупик» и убедитесь, что вершина без исходящих рёбер не обнуляет модель — сработала починка строки. Наконец, включите телепортацию «70%70\% в AA» и сравните ранги: персонализация меняет не только величину, но и порядок. Записывайте число итераций степенного метода: оно растёт вместе с α\alpha ровно так, как предсказывает оценка αt\alpha^{\,t}.

Не ограничивайтесь первой строкой рейтинга. Отмечайте расхождение ip^iπi\sum_i|\hat p_i-\pi_i| и то, сколько шагов нужно, чтобы оно стало меньше 0,050{,}05. Небольшое изменение вероятностей может заметно поменять порядок почти равных страниц — и это не шум измерения, а свойство самой шкалы.

Чего PageRank не измеряет

Авторы метода сказали это в той же работе, где ввели формулу. PageRank измеряет не истину и не качество, а положение вершины в потоке — при данном графе, данном α\alpha и данном vv. Отсюда три честные оговорки.

Во-первых, граф собирает робот, и он видит не весь веб: закрытые разделы, динамические страницы и медленные сайты представлены хуже. Во-вторых, ребро не различает одобрение и осуждение — ссылка в разоблачительной статье поднимает разоблачаемого. В-третьих, персонализация переносит власть на того, кто выбрал vv: связь с рекомендательными системами прямая, и сужение разнообразия источников здесь такое же реальное, как в ленте новостей.

Алгоритм HITS Клейнберга, появившийся одновременно с PageRank, разделяет две роли: собиратель ссылок и источник. Полезно помнить, что «важность» — не одно число, а семейство определений, и выбор между ними есть проектное решение, а не открытие закона природы.

Что унести с собой

PageRank — не магическая мера истины, а стационарный поток в выбранном графе. Тупики съедают вероятность, ловушки разрушают единственность, и обе болезни лечит одна и та же телепортация, которая заодно превращает задачу в сжимающее отображение с коэффициентом α\alpha. Разреженный степенной метод делает счёт возможным на миллиардах вершин: цена шага O(E)O(|E|), число шагов не зависит от размера графа. Персонализация линейна по vv и потому дёшева.

А интерпретация результата требует знать три вещи: как собран граф, что означает ребро и для кого определена релевантность. Первые две задаёте вы, третью — тот, кто выбирает vv.

Задачи