余弦相似度 余弦相似度衡量了两个向量的夹角,夹角越小越相似。
from sklearn.metrics.pairwise import cosine_distances i = [1,0,0,0] j = [1,0.5,0.5,0] print(cosine_distances([i,j]))UserCF算法主要包括两个步骤:
找到和目标用户兴趣相似的集合找到这个集合中的用户喜欢的, 且目标用户没有听说过的物品推荐给目标用户。主要点: 1.DataFrame的创建; 2.列表List的添加; 3.sort_values进行排序; 4.index 和 values 的使用 5.列表推导式的使用
import pandas as pd import numpy as np # 定义数据集, 也就是那个表格, 注意这里我们采用字典存放数据, 因为实际情况中数据是非常稀疏的, 很少有情况是现在这样 def loadData(): items={'A': {1: 5, 2: 3, 3: 4, 4: 3, 5: 1}, 'B': {1: 3, 2: 1, 3: 3, 4: 3, 5: 5}, 'C': {1: 4, 2: 2, 3: 4, 4: 1, 5: 5}, 'D': {1: 4, 2: 3, 3: 3, 4: 5, 5: 2}, 'E': {2: 3, 3: 5, 4: 4, 5: 1} } users={1: {'A': 5, 'B': 3, 'C': 4, 'D': 4}, 2: {'A': 3, 'B': 1, 'C': 2, 'D': 3, 'E': 3}, 3: {'A': 4, 'B': 3, 'C': 4, 'D': 3, 'E': 5}, 4: {'A': 3, 'B': 3, 'C': 1, 'D': 5, 'E': 4}, 5: {'A': 1, 'B': 5, 'C': 5, 'D': 2, 'E': 1} } return items,users # 导入数据 items,users = loadData() items_df = pd.DataFrame(items).T users_df = pd.DataFrame(users).T # 计算用户相似性矩阵 simlarity_matrix = pd.DataFrame(np.zeros((len(users),len(users))),index=[1,2,3,4,5],columns=[1,2,3,4,5]) for userID in users: for otheruserID in users: vec_user = [] vec_otheruser = [] if userID != otheruserID: for itemsID in items: # 为一个字典,每条数据为所有用户对当前物品的评分 item_rate = items[itemsID] if userID in item_rate and otheruserID in item_rate: vec_user.append(item_rate[userID]) vec_otheruser.append(item_rate[otheruserID]) # 这里可以获得相似性矩阵(共现矩阵) simlarity_matrix[userID][otheruserID] = np.corrcoef(np.array(vec_user),np.array(vec_otheruser))[1][0] #simlarity_matrix[userID][otheruserID] = cosine_similarity(np.array(vec_user),np.array(vec_otheruser)) print(simlarity_matrix) '''计算前N个相似的用户''' n = 2 simlarity_user = simlarity_matrix[1].sort_values(ascending=False).index.tolist()[:2] print(simlarity_user) '''计算最终得分''' user_tar_ave = np.mean([values for values in users[1].values()]) fenzi = 0 fenmu = 0 for user in simlarity_user: user_ave = np.mean([values for values in users[user].values()]) user_score = users[user]['E'] fenzi = fenzi + (user_score - user_ave)*simlarity_matrix[1][user] fenmu = fenmu + simlarity_matrix[1][user] final_score = user_tar_ave + fenzi/fenmu users_df.loc[1]['E']=final_score print(users_df)1. 计算物品之间的相似度 2. 根据物品的相似度和用户的历史行为给用户生成推荐列表(购买了该商品的用户也经常购买的其他商品
import pandas as pd import numpy as np # 定义数据集, 也就是那个表格, 注意这里我们采用字典存放数据, 因为实际情况中数据是非常稀疏的, 很少有情况是现在这样 def loadData(): items={'A': {1: 5, 2: 3, 3: 4, 4: 3, 5: 1}, 'B': {1: 3, 2: 1, 3: 3, 4: 3, 5: 5}, 'C': {1: 4, 2: 2, 3: 4, 4: 1, 5: 5}, 'D': {1: 4, 2: 3, 3: 3, 4: 5, 5: 2}, 'E': {2: 3, 3: 5, 4: 4, 5: 1} } users={1: {'A': 5, 'B': 3, 'C': 4, 'D': 4}, 2: {'A': 3, 'B': 1, 'C': 2, 'D': 3, 'E': 3}, 3: {'A': 4, 'B': 3, 'C': 4, 'D': 3, 'E': 5}, 4: {'A': 3, 'B': 3, 'C': 1, 'D': 5, 'E': 4}, 5: {'A': 1, 'B': 5, 'C': 5, 'D': 2, 'E': 1} } return items,users # 导入数据 items,users = loadData() items_df = pd.DataFrame(items).T users_df = pd.DataFrame(users).T # 计算物品的相似性 simlarity_matrix = pd.DataFrame(np.zeros((len(items),len(items))),index=['A','B','C','D','E'],columns=['A','B','C','D','E']) for items_ID in items: for otheritems_ID in items: items_gra = [] otheritems_gra = [] if items_ID != otheritems_ID: for users_ID in users: items_user = users[users_ID] if items_ID in items_user and otheritems_ID in items_user: items_gra.append(items_user[items_ID]) otheritems_gra.append(items_user[otheritems_ID]) #print(items_gra) #print(otheritems_gra) simlarity_matrix[items_ID][otheritems_ID] = np.corrcoef(np.array(items_gra),np.array(otheritems_gra))[0][1] print(simlarity_matrix) '''计算前N个相似的物品''' n = 2 simlarity_items = simlarity_matrix['E'].sort_values(ascending=False).index.tolist()[:2] print(simlarity_items) '''计算最终得分''' base_score = np.mean(np.array([i for i in items['E'].values()])) fenzi = 0 fenmu = 0 for item in simlarity_items: item_ave = np.mean(np.array([i for i in items[item].values()])) alice_gra = users[1][item] fenzi = fenzi + simlarity_matrix['E'][item]*(alice_gra - item_ave) fenmu = fenmu + simlarity_matrix['E'][item] alice_E = base_score +fenzi / fenmu print(alice_E) items['E'][1] = alice_E print(pd.DataFrame(items).T)UserCF 由于是基于用户相似度进行推荐,所以具备更强的社交特性,这样的特点非常适于用户少,物品多,时效性较强的场合,比如新闻推荐场景,因为新闻本身兴趣点分散,相比用户对不同新闻的兴趣偏好, 新闻的及时性,热点性往往更加重要,所以正好适用于发现热点,跟踪热点的趋势。另外还具有推荐新信息的能力,更有可能发现惊喜, 因为看的是人与人的相似性, 推出来的结果可能更有惊喜,可以发现用户潜在但自己尚未察觉的兴趣爱好。对于用户较少,要求时效性较强的场合,就可以考虑UserCF。
ItemCF 这个更适用于兴趣变化较为稳定的应用,更接近于个性化的推荐,适合物品少,用户多,用户兴趣固定持久,物品更新速度不是太快的场合,比如推荐艺术品,音乐,电影。
