Как преобразовать прямоугольную матрицу в стохастическую и неприводимую матрицу? - PullRequest
1 голос
/ 14 октября 2019

Я написал следующий код для преобразования матрицы в стохастическую и неприводимую матрицу. Я следовал за бумагой (глубже внутри PageRank), чтобы написать этот код. Этот код хорошо работает для квадратной матрицы, но дает ошибку для прямоугольных матриц. Как я могу изменить его, чтобы преобразовать прямоугольные матрицы в стохастические и неприводимые матрицы?

Мой код:

 import numpy as np
 P = np.array([[0, 1/2, 1/2, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1/3, 1/3, 0, 0, 1/3, 0], [0, 0, 0, 0, 1/2, 1/2], [0, 0, 0, 1/2, 0, 1/2]])
 #P is the original matrix containing 0 rows

 col_len = len(P[0])
 row_len = len(P)

 eT = np.ones(shape=(1, col_len))  # Row vector of ones to replace row of zeros
 e = eT.transpose()  # it is a column vector e
 eT_n = np.array(eT / col_len) # obtained by dividing row vector of ones by order of matrix

 Rsum = 0
 for i in range(row_len):
     for j in range(col_len):
         Rsum = Rsum + P[i][j]
 if Rsum == 0:
     P[i] = eT_n
 Rsum = 0
 P_bar = P.astype(float) #P_bar is stochastic matrix obtained by replacing row of ones by eT_n in P
 alpha = 0.85

 P_dbar = alpha * P_bar + (1 - alpha) * e * (eT_n) #P_dbar is the irreducible matrix
 print("The stocastic and irreducible matrix P_dbar is:\n", P_dbar)

Ожидаемый результат:

A rectangular stochastic and irreducible matrix.

Фактический результат:

Traceback (most recent call last):
  File "C:/Users/admin/PycharmProjects/Recommender/StochasticMatrix_11Aug19_BSK_v3.py", line 13, in <module>
P_dbar = alpha * P_bar + (1 - alpha) * e * (eT_n) #P_dbar is the irreducible matrix
ValueError: operands could not be broadcast together with shapes (5,6) (6,6)

1 Ответ

1 голос
/ 14 октября 2019

Вы пытаетесь умножить два массива разных форм. Это не сработает, поскольку один массив имеет 30 элементов, а другой - 36 элементов.

Необходимо убедиться, что массив e * eT_n имеет ту же форму, что и входной массив P.

Вы не используете значение row_len. Но если e имеет правильное количество строк, ваш код будет работать.

# e = eT.transpose()  # this will only work when the input array is square
e = np.ones(shape=(row_len, 1))  # this also works with a rectangular P 

Вы можете проверить правильность формы:

(e * eT_n).shape == P.shape 

Вы должны изучить документацию и учебные руководства, чтобы научиться использовать структуру данных ndarray. Он очень мощный, но также сильно отличается от собственных типов данных Python.

Например, вы можете заменить этот подробный и очень медленный вложенный цикл Python на операции векторизованного массива.

Исходный код (с фиксированным отступом):

for i in range(row_len):
    Rsum = 0
    for j in range(col_len):
        Rsum = Rsum + P[i][j]
    if Rsum == 0:
        P[i] = eT_n

Идиоматический код Numpy:

P[P.sum(axis=1) == 0] = eT_n

Кроме того, вам не нужно создавать массив eT_n,Поскольку повторяется только одно значение, вы можете вместо этого назначить скаляр 1/6.

# eT = np.ones(shape=(1, col_len))  
# eT_n = np.array(eT / col_len)

P[P.sum(axis=1) == 0] = 1 / P.shape[1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...