① 找到和目标用户兴趣相似的用户集合,三种常用的用户相似度指标是皮尔逊相关系数、余弦相关系数和杰卡德相关系数
② 根据用户相似度和相似个K个用户的得分,加权计算分数,得到目标用户对商品的评分
③找到这个集合中的用户所喜欢的,并且目标用户没有听说过的物品推荐给目标用户。
注意:各相似用户的评分应该减去均值进行计算,最终代入目标用户的均值+加权得分为目标用户的得分
#构建一个基于用户的推荐
def Recommendation_mean(uid,iid,similar,k=10):
"""减去平均数的计算方法"""
score = 0
weight = 0
user_id_action = freq_matrix[uid,:] #用户user_id 对所有商品的行为评分
item_id_action = freq_matrix[:,iid] #物品item_id 得到的所有用户评分
user_id_similar = similar[uid,:] #用户user_id 对所有用户的相似度
similar_index = np.argsort(user_id_similar)[-(k+1):-1] #最相似的k个用户的index(除了自己)
user_id_i_mean = np.sum(user_id_action)/user_id_action[user_id_action!=0].size#
for j in similar_index :
if item_id_action[j]!=0:
user_id_j_action = freq_matrix[j,:]
user_id_j_mean = np.sum(user_id_j_action)/user_id_j_action[user_id_j_action!=0].size
score += user_id_similar[j]*(item_id_action[j]-user_id_j_mean)
weight += abs(user_id_similar[j])
if weight==0:
return 0
else:
return user_id_i_mean + score/weight
#构建预测函数
def predict_mean(similar):
"""预测函数的功能: 传入相似度矩阵, 通过对每个用户和每个物品进行计算, 计算出一个推荐矩阵"""
user_count = freq_matrix.shape[0]#用户数
item_count = freq_matrix.shape[1]#商品数
predic_matrix = np.zeros((user_count,item_count))
for uid in range(user_count):
for iid in range(item_count):
if freq_matrix[uid,iid] == 0:
predic_matrix[uid,iid] = Recommendation_mean(uid,iid,similar)
return predic_matrix
def get_recommendation(user_prediction_matrix,k=5):
# 将用户预测数据, 构建成一个DataFrame
recommendation_df = pd.DataFrame(user_prediction_matrix,columns=dfpivot.columns,index=dfpivot.index)
# 将数据进行转换
recommendation_df = recommendation_df.stack().reset_index()
# 对列名进行修改
recommendation_df.rename(columns={0:"推荐指数"},inplace=True)
# 根据用户ID列进行分组
grouped = recommendation_df.groupby("用户id")
# 得到分组后的前几个数据
topk = grouped.apply(get_topk,k=k)
# 删除掉用户ID列
topk = topk.drop(["用户id"],axis=1)
# 删除掉多余的索引
topk.index = topk.index.droplevel(1)
# 索引重排
topk.reset_index(inplace=True)
return topk
① 计算物品之间的相似度;
其中,|N(i)|是喜欢物品i的用户数,|N(j)|是喜欢物品j的用户数,|N(i)&N(j)|是同时喜欢物品i和物品j的用户数。
②根据物品的相似度和用户的历史行为给用户生成推荐列表;
这里的N(u)代表用户喜欢的物品的集合,S(j,k)是和物品j最相似的的k个物品的集合,wij是物品j和i的相似度,r_ui代表用户u对物品i的兴趣。该公式的含义是,和用户历史上最感兴趣的物品月相似的物品,越有可能在用户的推荐列表中获得比较高的排名。
项集(Item):同时出现的项的集合,k项集即包含k个元素的项集;在本例中,{A}是1项集,{A C}是2项集;
支持度:在事务数据库 D 中所包含的项目集 X的所有事务数称作项集 X 的支持数, 记为 X 。support( X)=|X|/|D|*100%
支持度衡量关联规则重要性
置信度: 在事务数据库 D 中支持项集 X 的事务中支持项集 Y 的百分比称作规则 XY 在事务数据库 D 中的置信度。
置信度衡量关联规则的准确度
提升度:即在事件X出现的情况下事情Y出现的概率,相较于整体情况下事件Y出现的概率,提升了多少倍。
lift(X->Y) = lift(Y->X) = conf(X->Y)/supp(Y) = conf(Y->X)/supp(X) = P(XY)/(P(X)P(Y))
1.假设数据库为 D 由用户设置最小支持度 min_sup, 首先产生频繁项集 L;
2.再由频繁 k- 1 项集通过连接步连接成为 k 项集( 在 D 中,每个候选 k 项集为 min_sup 的 k 项成为频繁 k 项
集) ,验证 L 是不是包含 k 项集中的所有 k-1 子集, 重复此步骤,直到找不到更高的频繁项目集为止。
搜索频繁项集函数的伪代码实现如下:
findFrequent(ratings,nowItemsets,minSupport)://ratings 用户评
分
counts = {}//存放项和对应计数的字典
for user,reviews in ratings:
for itemset in nowItemsets://遍历现有项集
if itemset is subset of reviews://判断是否是子集
for otherItems in reviews - itemset://遍历未出
现在项集中的项
superSet = itemset | set(otherItems)//生成超集
counts[superSet] += 1//增加计数
return counts
抽取候选关联规则的伪代码如下:
candidateRules =[]//候选关联规则列表
for itemsetLen, itemsetCounts in frequentItems:
for itemset in itemsetCounts.keys():
for conclusion in itemset://遍历项集中的每一项把它作为结论
premise = itemset - set(conclusion)//项集中的其他项作为前提
candidateRules.add ((premise,conclusion))//向列表中添加候选规则
1.对数据库的扫描次数过多;
2.Apriori算法会产生大量的中间项集;
3.采用唯一支持度;
文章部分参考论文《基于关联规则的个性化推荐系统设计与实现》钱俊松 、冷文浩。