import math as mt
import numpy as np
import collections as cl
user_items = [
["Hadoop", "Big Data", "HBase", "Java", "Spark", "Storm", "Cassandra"],
["NoSQL", "MongoDB", "Cassandra", "HBase", "Postgres"],
["Python", "scikit-learn", "scipy", "numpy", "statsmodels", "pandas"],
["R", "Python", "statistics", "regression", "probability"],
["machine learning", "regression", "decision trees", "libsvm"],
["Python", "R", "Java", "C++", "Haskell", "programming languages"],
["statistics", "probability", "mathematics", "theory"],
["machine learning", "scikit-learn", "Mahout", "neural networks"],
["neural networks", "deep learning", "Big Data", "artificial intelligence"],
["Hadoop", "Java", "MapReduce", "Big Data"],
["statistics", "R", "statsmodels"],
["C++", "deep learning", "artificial intelligence", "probability"],
["pandas", "R", "Python"],
["databases", "HBase", "Postgres", "MySQL", "MongoDB"],
["libsvm", "regression", "support vector machines"]
]
- Рекомендация наиболее популярного выбора.
- Рекомендация по преференциям схожих клиентов (user-user)
- Рекомендации по схожести категорий (item-item)
1. Рекомендация наиболее популярного выбора.
Данный способ не учитывает особенностей выбора данного клиента в прошлом. По всем выборам, которые были сделаны в прошлом, выбираются наиболее популярные (наиболее частые) выборы, и предлагаются те, которых клиент еще не делал
most_popular = cl.Counter([j for i in user_items for j in i]).most_common()
def popular_recommendation_user(user_id, mx=5):
return [(k,v) for (k,v) in most_popular if k not in user_items[user_id]][:mx]
user_id = 0 # id клиента
print('Интересы клиента id{}: {}'.format(user_id, user_items[user_id]))
print('Рекомендации для клиента id{}: {}'.format(user_id, popular_recommendation_user(user_id)))
Интересы клиента id0: ['Hadoop', 'Big Data', 'HBase', 'Java', 'Spark', 'Storm', 'Cassandra'] Рекомендации для клиента id0: [('Python', 4), ('R', 4), ('statistics', 3), ('regression', 3), ('probability', 3)]
user_id = 1 # id клиента
print('Интересы клиента id{}: {}'.format(user_id, user_items[user_id]))
print('Рекомендации для клиента id{}: {}'.format(user_id, popular_recommendation_user(user_id)))
Интересы клиента id1: ['NoSQL', 'MongoDB', 'Cassandra', 'HBase', 'Postgres'] Рекомендации для клиента id1: [('Python', 4), ('R', 4), ('Java', 3), ('statistics', 3), ('Big Data', 3)]
user_id = 2 # id клиента
print('Интересы клиента id{}: {}'.format(user_id, user_items[user_id]))
print('Рекомендации для клиента id{}: {}'.format(user_id, popular_recommendation_user(user_id)))
Интересы клиента id2: ['Python', 'scikit-learn', 'scipy', 'numpy', 'statsmodels', 'pandas'] Рекомендации для клиента id2: [('R', 4), ('Java', 3), ('statistics', 3), ('Big Data', 3), ('regression', 3)]
2. Рекомендации по преференциям похожих клиентов (user-user)
Клиент «А» в прошлом сделал определенный набор выборов. Например, клиент мог выбрать ‘Big Data’, ‘Spark’, и ‘Python’. Основываясь на преференциях других клиентов, которые сделали похожие выборы, что еще мы можем порекомендовать данному клиенту? Данный способ рекомендаций основывается на предположении, что если клиенты «А» и «В» имеют схожие интересы, то что нравится «В» — скорее всего понравится и «А». На практике, этот способ рекомендаций реализуется, когда мы звоним друзьям и спрашиваем совета, какой фильм посмотреть? Математически задача решается следующим образом:
- Определяется размерность пространства, в котором будет решаться задача. Размерность равняется количеству уникальных выборов.
- Каждый клиент отображается в полученном n-мерном пространстве в виде вектора c координатами (0,1):
- 1, если клиент делал выбор по данной оси координат
- 0, если клиент не делал данный выбор
- В n-мерном пространстве выбираются вектора клиентов, наиболее «близкие» вектору клиента, для которого дается рекомендация. «Близость» определяется по cosine_similarity
- Предпочтения выбранных, наиболее «близких» клиентов суммируется и топовые преференции выдаются в виде рекомендации.
Для начала, давайте определим функцию cosine similarity(v1,v2)
, с помощью который мы будем измерять «близость» двух клиентов в n-мерном пространстве, или, выражаясь простым языком, «схожесть» клиентов v1 и v2.
def cosim(v1,v2):
return np.dot(v1,v2)/ mt.sqrt(np.dot(v1,v1)*np.dot(v2,v2))
unique_items = sorted({j for i in user_items for j in i})
unique_items[:5]
['Big Data', 'C++', 'Cassandra', 'HBase', 'Hadoop']
- 1, если такой выбор делался данным клиентом в прошлом
- 0, если клиент не делал такой выбор в прошлом
def make_vector_items(items):
return [1 if i in items else 0 for i in unique_items]
user_items_matrix = [make_vector_items(items) for items in user_items]
user_items_matrix
, где строки представляют клиентов (m), а столбцы представляют сделанные ими выборы (n).user_items_matrix
на основе cosim()
мы можем определить список наиболее схожих клиентов:def similar_users(user_ID):
pairs = [(user_id, cosim(user_items_matrix[user_ID], user_interest))
for user_id, user_interest in enumerate(user_items_matrix)
if user_id != user_ID
and cosim(user_items_matrix[user_ID], user_interest) > 0]
return sorted(pairs, key = lambda x: x[1], reverse =1)
similar_users(0)
[(9, 0.56694670951384085), (1, 0.33806170189140661), (8, 0.1889822365046136), (13, 0.1690308509457033), (5, 0.15430334996209191)]
def user_user_recommendation(user_ID, mx = 5):
recommendation = cl.defaultdict(float)
# calculate recommendations over similar users
for user_id, cosim_similarity in similar_users(user_ID):
for interest in user_items[user_id]:
recommendation[interest] += cosim_similarity
# sort them out
recommendation = sorted(recommendation.items(), key = lambda x: x[1], reverse=1)
# exclude already existing items
recommendation = [i for i in recommendation if i[0] not in user_items[user_ID]]
return recommendation[:mx]
user_id = 0
print('Интересы клиента id_{0}: \n{1}\n\n\
Рекомендации для клиента id_{0} по наиболее популярным запросам: \n{2}\n\n\
Рекомендации для клиента id_{0} по схожим клиентам: \n{3}'\
.format(user_id,user_items[user_id],popular_recommendation_user(user_id),user_user_recommendation(user_id)))
Интересы клиента id_0: ['Hadoop', 'Big Data', 'HBase', 'Java', 'Spark', 'Storm', 'Cassandra'] Рекомендации для клиента id_0 по наиболее популярным запросам: [('Python', 4), ('R', 4), ('statistics', 3), ('regression', 3), ('probability', 3)] Рекомендации для клиента id_0 по схожим клиентам: [('MapReduce', 0.56694670951384085), ('Postgres', 0.50709255283710997), ('MongoDB', 0.50709255283710997), ('NoSQL', 0.33806170189140661), ('artificial intelligence', 0.1889822365046136)]
3. Рекомендации по схожести категорий (item-item)
Клиент уже выбрал несколько категорий, например ‘Big Data’, ‘Spark’ и ‘Python’. Каждая выбранная категория, в свою очередь, также имеет наиболее близкие категории. Основываясь на схожести категорий, что еще мы можем посоветовать ему? Данный способ основывается на рекомендации категорий, которые наиболее «близки» уже сделанным выборам:
- «Близость» определяется на основе cosine similarity
- На основе cosine similarity выбираются категории, которые наиболее близки уже сделанным выборам
- Cosine similarity суммируется по всем выбранным (наиболее близким) категориям и выбираются топовые рекомендации, которых нет среди уже сделанных выборов.
Вспомним, что в основе рекомендаций лежал лист выборов, где каждый элемент листа ассоциировался с клиентом, а для каждого клиента был вектор выборов.
user_items
[['Hadoop', 'Big Data', 'HBase', 'Java', 'Spark', 'Storm', 'Cassandra'], ['NoSQL', 'MongoDB', 'Cassandra', 'HBase', 'Postgres'], ['Python', 'scikit-learn', 'scipy', 'numpy', 'statsmodels', 'pandas'], ['R', 'Python', 'statistics', 'regression', 'probability'], ['machine learning', 'regression', 'decision trees', 'libsvm'], ['Python', 'R', 'Java', 'C++', 'Haskell', 'programming languages'], ['statistics', 'probability', 'mathematics', 'theory'], ['machine learning', 'scikit-learn', 'Mahout', 'neural networks'], ['neural networks', 'deep learning', 'Big Data', 'artificial intelligence'], ['Hadoop', 'Java', 'MapReduce', 'Big Data'], ['statistics', 'R', 'statsmodels'], ['C++', 'deep learning', 'artificial intelligence', 'probability'], ['pandas', 'R', 'Python'], ['databases', 'HBase', 'Postgres', 'MySQL', 'MongoDB'], ['libsvm', 'regression', 'support vector machines']]
item_users_matrix = [[1 if i in j else 0 for j in user_items] for i in unique_items]
item_users_matrix[:5]
[[1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]]
def similar_items(interest_id):
pairs = [(unique_items[i], cosim(item_users_matrix[interest_id], item))
for i, item in enumerate(item_users_matrix)
if i != interest_id and cosim(item_users_matrix[interest_id], item) > 0
]
pairs = sorted(pairs, key = lambda x: x[1], reverse =1)
return pairs
similar_items(0)[:5]
[('Hadoop', 0.81649658092772615), ('Java', 0.66666666666666663), ('MapReduce', 0.57735026918962584), ('Spark', 0.57735026918962584), ('Storm', 0.57735026918962584)]
unique_items_position = {k:v for v,k in enumerate(unique_items)}
print(unique_items[:3])
print(unique_items_position['Big Data'])
['Big Data', 'C++', 'Cassandra'] 0
- найдет схожие категории для всех сделанных выборов
- просуммирует cosine simialrity для всех схожих категорий
- выберет топовые 5 рекомендаций
def item_item_recommendation(user_id, mx=5):
rec = cl.defaultdict(float)
for item in user_items[user_id]:
sim_items = similar_items(unique_items_position[item])
for it, similarity in sim_items:
rec[it] += similarity
rec = sorted(rec.items(), key=lambda x: x[1], reverse = 1)
rec = [i for i in rec if i[0] not in user_items[user_id]]
return rec[:mx]
user_id = 0
print('Интересы клиента id_{0}: \n{1}\n\n\
Рекомендации для клиента id_{0} по наиболее популярным запросам: \n{2}\n\n\
Рекомендации для клиента id_{0} user-user: \n{3}\n\n\
Рекомендации для клиента id_{0} item-item: \n{4}'\
.format(user_id,
user_items[user_id],
popular_recommendation_user(user_id),
user_user_recommendation(user_id),
item_item_recommendation(user_id)))
Интересы клиента id_0: ['Hadoop', 'Big Data', 'HBase', 'Java', 'Spark', 'Storm', 'Cassandra'] Рекомендации для клиента id_0 по наиболее популярным запросам: [('Python', 4), ('R', 4), ('statistics', 3), ('regression', 3), ('probability', 3)] Рекомендации для клиента id_0 user-user: [('MapReduce', 0.56694670951384085), ('Postgres', 0.50709255283710997), ('MongoDB', 0.50709255283710997), ('NoSQL', 0.33806170189140661), ('artificial intelligence', 0.1889822365046136)] Рекомендации для клиента id_0 item-item: [('MapReduce', 1.8618073195657989), ('Postgres', 1.3164965809277263), ('MongoDB', 1.3164965809277263), ('NoSQL', 1.2844570503761732), ('databases', 0.57735026918962584)]
Write a comment: