Матрица рейтинга элементов пользователя: IndexError - PullRequest
0 голосов
/ 04 июля 2018

urm моего информационного кадра имеет форму (96438, 3)

user_id anime_id    user_rating
0   1   20  7.808497
1   3   20  8.000000
2   5   20  6.000000
3   6   20  7.808497
4   10  20  7.808497

Я пытаюсь построить матрицу рейтинга предмета:

X = urm[["user_id", "anime_id"]].as_matrix()
y = urm["user_rating"].values
n_u = len(urm["user_id"].unique())
n_m = len(urm["anime_id"].unique())

R = np.zeros((n_u, n_m))
for idx, row in enumerate(X):
    R[row[0]-1, row[1]-1] = y[idx]

если код преуспевает, матрица выглядит так: (я заполнил NaN 0)

Matrix of item_rating-user

с индексом user_id, anime_id в столбцах и оценкой значения (я получил эту матрицу из таблицы сводных данных)

в каком-то уроке работает, но там я получил

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-278-0e06bd0f3133> in <module>()
     15 R = np.zeros((n_u, n_m))
     16 for idx, row in enumerate(X):
---> 17     R[row[0]-1, row[1]-1] = y[idx]

IndexError: index 5276 is out of bounds for axis 1 with size 5143

Ответы [ 2 ]

0 голосов
/ 26 июля 2019

Я попробовал второе предложение dennlinger , и оно сработало для меня. Это был код, который я написал:

def id_to_index(df):
    """
    maps the values to the lowest consecutive values
    :param df: pandas Dataframe with columns user, item, rating
    :return: pandas Dataframe with the extra columns index_item and index_user
    """

    index_item = np.arange(0, len(df.item.unique()))
    index_user = np.arange(0, len(df.user.unique()))

    df_item_index = pd.DataFrame(df.item.unique(), columns=["item"])
    df_item_index["new_index"] = index_item
    df_user_index = pd.DataFrame(df.user.unique(), columns=["user"])
    df_user_index["new_index"] = index_user

    df["index_item"] = df["item"].map(df_item_index.set_index('item')["new_index"]).fillna(0)
    df["index_user"] = df["user"].map(df_user_index.set_index('user')["new_index"]).fillna(0)


    return df
0 голосов
/ 04 июля 2018

Я предполагаю, что у вас есть непоследовательные идентификаторы пользователей (или идентификаторы фильмов), что означает, что существуют индексы, которые либо имеют

  • нет рейтинга или
  • нет фильма

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

В этом случае у вас есть два варианта:

  • Вы можете определить матрицу размером urm["user_id"].max() с помощью urm["anime_id"].max()
  • Создайте словарь, который сопоставляет ваши значения с наименьшими последовательными значениями.

Недостаток первого подхода, очевидно, заключается в том, что он требует от вас хранить матрицу большего размера. Кроме того, вы можете использовать scipy.sparse для создания матрицы из имеющегося у вас формата данных (обычно называемого форматом координатной матрицы ).
Потенциально вы можете сделать что-то вроде этого:

from scipy import sparse
# scipy expects the data in (value_column, (x, y))
mat = sparse.coo_matrix((urm["user_rating"], (urm["user_id"], urm["anime_id"]))
# if you want it as a dense matrix
dense_mat = mat.todense()

Затем вы также можете перейти ко второму предложению, как я ранее спрашивал здесь

...