核心思想:通过隐含特征联系用户兴趣和物品。
我的理解是LFM 就是对物品基于权重进行分类,并同时依据用户对每一类的兴趣来确定用户感兴趣的物品。看似是把一个大问题分解成了两个小问题。
基于兴趣分类的方法大概需要解决三个问题:
对于第一个问题,采用隐含语义分析技术。该技术采取基于用户统计行为的自动聚类。
对于第二个问题,LFM 通过如下公式计算用户u对物品i 的兴趣:
这里求出 qi pu,k 和 qi,k 是通过最小化下面的损失函数得到的:
def RandomSelectNegativeSample(user, user_items):
ret = dict()
items_pool = []#包含所有的item,有重复的,之所以不用set是因为要遵循(2)
for example, items in user_items.items():
for item in items:
items_pool.append(item)
items_pool=list(items_pool)
for i in user_items[user]:
ret[i] = 1 #正样本为1
n = 0
for i in range(0, len(user_items[user]) * 3):
item = items_pool[random.randint(0, len(items_pool) - 1)]
if item in ret.keys():
continue
ret[item]=0 #负样本为0
n += 1
if n > len(user_itmes[user]): #确保正负样本数目相似
break
return ret
最小化上面的损失函数,求得 pu,k 和 qi,k 。 这里通常有两种方法,一种是随机梯度下降法 (SGD),另一种是交替最小二乘法(ALS). 推荐系统这本书介绍的是SGD, 步骤如下:
1.对 pu,k 和 qi,k 求取偏导数,确定最速下降方向:
2.将参数沿着最速下降方向向前推进,迭代,直到参数收敛。
def LatentFactorModel(user_items, F, N, alpha, lam):
[P,Q]=InitModel(user_items,F)
for step in range(0,N):
for user, items in user_items.items():
samples=RandomSelectNegativeSample(user,user_items)
for item, rui in samples.items():
p=0
for i in range(0,F):
p+=P[user][i]*Q[i][item]
eui=rui-p
for f in range(0,F):
P[user][f]+=alpha*(eui*Q[f][item]-lam*P[user][f])
Q[f][item]+=alpha*(eui*P[user][f]-lam * Q[f][item])
return P, Q
#下面是初始话P,Q,全设为1
def InitModel(user_items,F):
P={}
Q={}
for u, items in user_items.items():
if u not in P :
P[u]={}
for f in range(0,F):
P[u][f]=1
for f in range(0,F):
if f not in Q:
Q[f]={}
for i in items:
Q[f][i]=1
return P, Q
计算了P,Q后,下来就是根据 Perference(u,i) 计算兴趣度,然后推荐了。下面是推荐代码:
def Recommend(user,P,Q):
rank=dict()
for f, puf in P[user].items():
for i, qfi in Q[f].items():
if i not in rank:
rank[i]=puf*qfi
rank[i]+=puf*qfi
return rank
就这个推荐代码,我有几点还没弄清楚:1. 这样计算出来的会包含用户以购买的物品,这不应该啊。2. 如果去除用户已购买的物品,那么之前采样的负样本怎么办,去除吗?有必要再看看资料,解决这两个问题。3. 总感觉这样生成的负样本,不是就是说认为人家用户不喜欢,这是不是太绝对了,人用户也许是喜欢只是没看见。不知道我是不是对这个算法理解的有问题。
在LFM中,重要的参数有四个:1.隐特征的个数F; 2.学习速率 α ; 3.正则化参数 λ ; 4.负样本/正样本比例ratio. 书上的实验看出ratio对LFM的性能影响最大。当数据集非常稀疏时,LFM的性能会明显下降,甚至不如UserCF和ItemCF. LFM很难实现实时推荐,训练时非常耗时, 因为要在所有用户行为记录上反复迭代才能获得比较好的性能。另外,在新闻推荐时冷启动非常明显。
为了解决LFM的一些缺陷,很多论文中提出对 rui 的修正,这个后续我得看看正方面的论文,再来补上。
下面简单总结下LFM与基于邻域的方法的比较:
1.理论基础:LFM具有比较好的理论基础,是一种学习方法。基于的邻域的方法是一种基于统计的方法,没有学习过程。
2.离线计算的空间复杂度:LFM低于UserCF和ItemCF
3.离线计算的时间复杂度:一般情况下, LFM高于UserCF和ItemCF,主要是LFM需要多次迭代。但是书上又说 总体上,这两种算法在时间复杂度上没有质的区别,没弄明白,这是为什么呢。
4.在线实时推荐:LFM不能进行在线实时推荐。
5.推荐解释:ItemCF支持很好的推荐解释,UserCF和LFM都无法提供。
LFM这块看了一篇《Matrix factorization techniques for recommender systems》, 里面提出了一些对(1) 和(2)的修正。 比如,通过置信度权重来处理我们所认为的负样本,也就是没有反馈的物品。就是说对更确信用户的项赋以较大的权重,对于没有反馈的项,赋以较小的权重。则(2)变成了
pu,k 和 qi,k 是通过最小化下面的损失函数得到的: