Найти самого похожего пользователя

Необходимо найти самого похожего пользователя. Посчитать косинусное сходство между этим пользователем и всеми пользователями из массива user_stats

Имеется матрица покупок в интернет-магазине. Столбец А - ID пользователя. Остальные столбцы - количество покупок категорий товаров этим пользователем. Матрица в виде numpy array:

users_stats = np.array(
    [
        [2, 1, 0, 0, 0, 0],
        [1, 1, 2, 1, 0, 0],
        [2, 0, 1, 0, 0, 0],
        [1, 1, 2, 1, 0, 1],
        [0, 0, 1, 2, 0, 0],
        [0, 0, 0, 0, 0, 5],
        [1, 0, 0, 0, 0, 0],
        [0, 1, 1, 0, 0, 0],
        [0, 0, 0, 1, 1, 3],
        [1, 0, 0, 2, 1, 4]
    ], 
    np.int32
)

На сайт заходит очередной посетитель, о покупках которого известно следующее:

next_user_stats = np.array([0, 1, 2, 0, 0, 0])

Необходимо найти самого похожего пользователя. Т. е. посчитайте косинусное сходство между этим пользователем и всеми пользователями из массива user_stats. В задании нудно использовать библиотеку numpy.

Есть решение для похожего примера, но в нем нет списка в списке и поэтому он не работает на данной задаче:

def cosine( users_stats, next_user_stats ):
    # длины векторов
    users_stats_Length = np.linalg.norm( users_stats )
    next_user_stats_Length = np.linalg.norm( next_user_stats )
    
    return np.dot( users_stats, next_user_stats ) / ( users_stats_Length * next_user_stats_Length )

Вот результат:

cosine( users_stats, next_user_stats )

array([0.04688072, 0.23440362, 0.09376145, 0.23440362, 0.09376145,
       0.        , 0.        , 0.14064217, 0.        , 0.        ])

Ответы (1 шт):

Автор решения: Pak Uula

Вам нужно применить cosine к каждой строке матрицы users_stats. В numpy для этого есть функция apply_along_axis:

muls = np.apply_along_axis(cosine, 1, users_stats, next_user_stats)

Второй аргумент 1 означает, что функция cosine должна вызываться для строк. Последний аргумент next_user_stats будет подставляться вторым аргументом в cosine. Вызов этой функции эквивалентен вот какому коду на Python:

muls = np.array([cosine(row, next_user_stats) for row in users_stats])

В обоих случаях результат равен

array([0.2       , 0.84515425, 0.4       , 0.79056942, 0.4       ,
       0.        , 0.        , 0.9486833 , 0.        , 0.        ])

Функция np.argmax находит индекс элемента, который соответствует максимальному значению массива (нумерация с нуля):

best_user = np.argmax(muls)

Наилучшее совпадение - пользователь номер 7.

→ Ссылка