2016-05-01 6 views
1

Я пытаюсь написать эту matlab implementation в Python, но я не понимаю, несколько моментов:PageRank реализация питон, алгоритм

last_v = те (N, 1) * инф;

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

While (норма (v - last_v, 2)> v_quadratic_error)

Что я понимаю ложь ?

Это путь, я пытался это сделать:

from numpy import * 
def pagerank(M,d,v_quadratic_error): 
count = 0 
N=M.shape[1] 
v=random.rand(N,1) 
v=v/linalg.norm(v) 
ainf=array([[inf]]) 
last_v = dot(ones((N,1)),ainf) 
R = d*M + ((1-d)/N * ones((N,N))) 
while linalg.norm(v-last_v,2) > v_quadratic_error: 
    last_v = v 
    v = dot(R,v) 
    count+=1 
    print 'iteration #', count 
return v 

ответ

1

В Matlab/октава:

octave:4> last_v = ones(N, 1) * inf; 
octave:10> norm(v - last_v, 2) 
ans = Inf 
octave:13> norm(v - last_v, 2) > v_quadratic_error 
ans = 1 

В Python:

In [139]: last_v = np.dot(np.ones((N,1)),ainf) 
In [140]: np.linalg.norm(v - last_v, 2) 
Out[140]: nan 
In [141]: np.linalg.norm(v - last_v, 2) <= v_quadratic_error 
Out[141]: False 

Так условие истинно в Matlab/октава, но подобное выражение в Python является значение False. В Python, вместо того, чтобы использовать

while linalg.norm(v-last_v,2) > v_quadratic_error: 

вы могли бы использовать

while True: 
    last_v = v 
    ... 
    if np.linalg.norm(v - last_v, 2) <= v_quadratic_error: break 

Это гарантирует, что поток выполнения входит в while-loop по крайней мере один раз, а затем распадается, когда условие истинно. К этому моменту last_v будет иметь конечное значение, поэтому исключается проблема NaN и Inf.


import numpy as np 

def pagerank(M, d, v_quadratic_error): 
    count = 0 
    N = M.shape[1] 
    while True: 
     v = np.random.rand(N, 1) 
     if (v != 0).all(): break 
    v = v/np.linalg.norm(v) 
    R = d * M + ((1 - d)/N * np.ones((N, N))) 
    while True: 
     last_v = v 
     v = np.dot(R, v) 
     count += 1 
     print('iteration # {}: {}'.format(count, np.isfinite(v))) 
     if np.linalg.norm(v - last_v, 2) <= v_quadratic_error: break 
    return v 

M = np.array(np.mat('0 0 0 0 1 ; 0.5 0 0 0 0 ; 0.5 0 0 0 0 ; 0 1 0.5 0 0 ; 0 0 0.5 1 0')) 
print(pagerank(M, 0.80, 0.001)) 

дает (что-то подобное)

[[ 0.46322263] 
[ 0.25968575] 
[ 0.25968575] 
[ 0.38623472] 
[ 0.48692059]] 
+0

Великий, спасибо. – Jotwege

0

Да, вы правы, линия даст вектор бесконечностей. Также можно напрямую использовать inf: https://de.mathworks.com/help/matlab/ref/inf.html ->inf(N,1).

Условие, хотя не даст ложных результатов, почему? Пожалуйста, обратите внимание на евклидовой нормы: https://en.wikipedia.org/wiki/Euclidean_distance -> Норма вектора инфа (вычитаются некоторыми случайными значениями, которые будут эффективно все еще дают вектор infs) уступит inf снова, так

inf > v_quadratic_error 

будет правдой. Внутри цикла last_v будет перезаписан, и, следовательно, в последующих итерациях он будет сходиться.

Смежные вопросы