Эффективное по памяти решение для расчетов сходства предметов - данные о покупках

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

Мой набор данных выглядит следующим образом (пример, полный из которых содержит более 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.

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

результат функции кросс-таблицы панды

где у меня есть одна строка на 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, я должен использовать скудную разреженную матрицу, поскольку она ускоряет вычисления (вычисления подобия, нормализацию векторов), потому что входными данными будут массивы, а не кадры данных.

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

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

scipy.sparse.csr_matrix(df.values)

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

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

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

0 ответов

Другие вопросы по тегам