эффективное по памяти решение для расчетов сходства предметов - данные о покупках - PullRequest
0 голосов
/ 29 августа 2018

Я работаю над рекомендациями продукта.

Мой набор данных выглядит следующим образом (Пример, полный набор содержит более 110 000 строк и более 80000 уникальных product_id ):

          user_id                     product_id

0     0E3D17EA-BEEF-493                12909837
1     0FD6955D-484C-4FC8-8C3F          12732936
2     CC2877D0-A15C-4C0A               Gklb38
3     b5ad805c-f295-4852               12909841
4     0E3D17EA-BEEF-493                12645715

Я хочу рассчитать косинусное сходство между продуктами на основе приобретенных продуктов на пользователя.

Почему? Мне нужен конечный результат:

список 5 самых похожих товаров для каждого product_id .

Итак, я подумал, что первое, что мне нужно сделать, - это преобразовать фрейм данных в этот формат:

crosstab pandas function result

где у меня одна строка на user_id, а столбцы - product_ids. Если пользователь купил product_id X, то соответствующая строка столбца будет содержать значение 1, иначе 0.

Я сделал это с помощью функции кросс-таблицы панд данных.

crosstab_df = pd.crosstab(df.user_id, df.product_id).astype('bool').astype('int')

После этого я рассчитал сходство между продуктами.

def calculate_similarity(data_items):
"""Calculate the column-wise cosine similarity for a sparse
matrix. Return a new dataframe matrix with similarities.
"""
# create a scipy sparse matrix
data_sparse = sparse.csr_matrix(data_items)
#pairwise similarities between all samples in data_sparse.transpose()
similarities = cosine_similarity(data_sparse.transpose())
#put the similarities between products in a dataframe
sim = pd.DataFrame(data=similarities, index= data_items.columns, columns= data_items.columns)
return sim

similarity_matrix = calculate_similarity(crosstab_df)

Я знаю, что это неэффективно, потому что кросс-таблица не работает хорошо, когда есть много строк и много столбцов, что я должен обработать. Итак, я подумал о том, чтобы вместо использования Crosstab DataFrame, я должен использовать scipy разреженную матрицу , поскольку это ускоряет вычисления (вычисления подобия, нормализацию векторов), потому что входные данные будут массивом, а не кадром данных.

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

Я нашел в других вопросах ответы, которые:

scipy.sparse.csr_matrix(df.values)

можно использовать, но в моем случае, я думаю, я могу использовать его только после применения кросс-таблицы .. пока я хочу избавиться от шага кросс-таблицы.

Кроме того, люди предложили использовать scipy coo_matrix , но я не понял, как я могу применить его в моем случае для достижения желаемых результатов.

Я ищу эффективное для памяти решение , поскольку начальный набор данных может увеличиваться на тысячи строк и сотни тысяч product_id ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...