一、基于物品的协同过滤 ItemCF
\[sim(i,j) =\frac{\sum_{u\in N(i) \bigcap N(j)} 1}{\sqrt{|N(i)||N(j)|}} \]
1、协同过滤实现过程
建立user-item 的倒排表,一个字典结构:
user_item_dict = {'Tom':['乱世佳人','精武门',...],'Bob':['魂断蓝桥','活着',...],...}
使用sim_dict 来保存物品相似度矩阵。物品相似度的确定:遍历user_item_dict所有用户,其value 列表中共现的两个item 相似度+1。在循环结束之后,便得到物品相似度矩阵。
sim_dict = {} # 先保存分子信息,最后得到最终的物品相似度矩阵
num_dict = {} # 保存分母信息
for user in user_item_dict: # 计算分子,使用了隐式评分数据集
items = user_item_dict[user]
for i in range(len(items)):
item_u = items[i]
if item_u not in num_dict:
num_dict[item_u] = 0
num_dict[item_u] += 1
if item_u not in sim_dict:
sim_dict[item_u] = {}
for j in range(len(items)):
if j ==i:continue
item_v = items[j]
if v not in sim[item_u]
sim[item_u][item_v] = 0
sim[item_u][item_v] += 1
# 分子/分母
for u in sim_dict:
for v in sim_dict[u]:
sim[u][v] /= math.sqrt(num_dict[u]*num_dict[v])
2、协同过滤推荐过程
给用户\(u\)进行推荐时,用户\(u\)对物品\(i\)的喜好程度\(p(u,i)\),可以想到的是,遍历用户看过的物品\(j\),然后找到\(i\)与的\(j\)相似度:
\[p(u,i) = \sum_{j\in N(u)}sim(i,j) \]
二、问题及其改进:时间上下文相关的ItemCF算法
1、物品相似度
用户在相隔很短时间内喜欢的物品具有更高相似度。以电影推荐为例,用户今天看的电影和昨天看的电影其相似度在统计意义上应该大于用户今天看的电影和一年前看的电影的相似度。
2、推荐阶段
用户近期行为相比用户很久之前的行为,更能体现用户现在的兴趣。因此在预测用户现在的兴趣时,应该增加用户近期行为的权重,优先推荐和他近期喜欢的物品相似的物品。
3、改进:
在得到时间信息(用户对物品产生行为的时间)后,通过下面公式计算物品相似度:
\[sim(i,j) =\frac{\sum_{u\in N(i) \bigcap N(j)} f(|t_{ui}-t_{uj}|)}{\sqrt{|N(i)||N(j)|}} \]
不再是乘1,而是引入了和时间有关的衰减项\(f(|t_{ui}-t_{uj}|)\),其中:
\(t_{ui}\)为用户\(u\)对物品\(i\)产生行为的时间。\(f\)函数的含义是:用户对物品i和j产生行为的时间越远,则\(f(|t_{ui}-t_{uj}|)\)越小。衰减函数的选择众多,比如:
\[f(|t_{ui}-t_{uj}|) = \frac{1}{1+\alpha |t_{ui}-t_{uj}|} \]
在推荐阶段:
\[p(u,i) = \sum_{j\in N(u)}sim(i,j) \frac{1}{1+\beta|t_0-t_{uj}|} \]
其中,\(t_0\)为当前时间。\(t_{uj}\)越靠近\(t_0\),和物品\(j\)越相似的物品就有更大的权值。\(\beta\)为衰减参数。