转载一篇再推荐系统领域工程实用性很强的文章:
http://www.shuang0420.com/2017/02/17/%E6%8E%A8%E8%8D%90%E7%B3%BB%E7%BB%9F--%E9%9A%90%E8%AF%AD%E4%B9%89%E6%A8%A1%E5%9E%8BLFM/
本篇文章主要介绍 隐语义模型 LFM(latent factor model)。
隐语义模型最早在文本挖掘领域被提出,用于找到文本的隐含语义,相关名词有 LSI、pLSA、LDA 等。在推荐领域,隐语义模型也有着举足轻重的地位。下述的实验设计见 推荐系统–用户行为和实验设计
核心思想: 通过隐含特征(latent factor)联系用户兴趣和物品。具体来说,就是对于某个用户,首先得到他的兴趣分类,然后从分类中挑选他可能喜欢的物品。
基于兴趣分类的方法需要解决3个问题:
如何对物品进行分类?
物品分类往往是通过人工编辑进行,然而人工编辑存在很多缺陷
隐含语义分析技术(latent variable analysis)采取基于用户行为统计的自动聚类,可以较好解决上面提出的问题。
隐含语义分析技术有很多著名的模型和方法,相关的名词有 pLSA、LDA、隐含类别模型(latent class model)、隐含主题模型(latent topic model)、矩阵分解(matrix factorization),这些技术和方法本质上是相通的,很多方法都可以用于个性化推荐系统。本篇只介绍 LFM。
计算用户 u 对物品 i 的兴趣
我们这里用的是隐反馈数据集,只有正样本(用户喜欢什么物品),而没有负样本(用户对什么物品不感兴趣),因此第一个问题是如何对每个用户产生负样本。
Rong Ran 提出了以下方法。
Rong Ran 表示第一种负样本太多,计算复杂度高,精度也差,而第三种优于第二种,第二种优于第四种。
另外需要遵循的原则是:
负样本采样过程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
'''
items: dictionary of items where user takes action
items_pool: list of candidate items; the more popular item i is, the more often item i appear
'''
def RandomSelectNegativeSample(self, items):
ret = dict()
for i in items.keys():
ret[i] = 1
n=0
for i in range(0, len(items) * 3): # make the number of negative samples close to that of positvie
item = items_pool[random.randint(0, len(items_pool) - 1)]
if item in ret:
continue
ret[item] = 0
n+=1
if n > len(items):
break
return ret
|
得到一个用户-物品集 K={(u,i)},如果(u,i)是正样本,则有 rui=1rui=1,否则rui=0rui=0,然后通过随机梯度下降来优化损失函数找到最合适的参数 p 和 q:
λ||pu||2+λ||qi||2λ||pu||2+λ||qi||2 是防止过拟合的正则化项,λλ 通过实验获得。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def LatentFactorModel(user_items, F, N, alpha, lambda):
[P, Q] = InitModel(user_items, F)
for step in range(0,N):
for user, items in user_items.items():
samples = RandSelectNegativeSamples(items)
for item, rui in samples.items():
eui = rui - Predict(user, item)
for f in range(0, F):
P[user][f] += alpha * (eui * Q[item][f] - lambda * P[user][f])
Q[item][f] += alpha * (eui * P[user][f] - lambda * Q[item][f])
alpha *= 0.9
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
return rank
|
4 个隐类中排名最高的一些电影
参数:
实验发现,ratio 对 LFM 性能影响最大,随着负样本数目的增加,LFM 的准确率和召回率有明显提高,当 ratio > 10后趋于稳定,同时,随着负样本数目增加,覆盖率不断降低,流行度不断增加,说明 ratio 参数控制了推荐算法发掘长尾的能力。另外,与之前实验比较,在所有指标上都优于 UserCF 和 ItemCF。然而当数据集非常稀疏时,LFM 的性能会明显下降。
固定 F=100, alpha=0.02, lambda=0.01,研究 ratio 对推荐性能的影响。
LFM 模型在实际使用中有一个困难,就是很难实现实时推荐。经典的 LFM 模型每次训练都需要扫描所有的用户行为记录,并且需要在用户行为记录上反复迭代来优化参数,所以每次训练都很耗时,实际应用中只能每天训练一次。在新闻推荐中,冷启动问题非常明显,每天都会有大量的新闻,这些新闻往往如昙花一现,在很短的时间获得很多人的关注,然后在很短时间内失去关注,实时性就非常重要。雅虎对此提出了一个解决方案。
首先,利用新闻链接的内容属性(关键词、类别等)得到链接 i 的内容特征向量 yi,其次,实时收集用户对链接的行为,并且用这些数据得到链接 i 的隐特征向量 qi,然后,利用下面的公式预测用户 u 是否会单击链接 i:
yiyi: 根据物品的内容属性直接生成
xukxuk: 用户 u 对内容特征 k 的兴趣程度,用户向量 xuxu 可以根据历史行为记录获得,每天计算一次
pupu,qiqi: 实时拿到的用户最近几小时的行为训练 LFM 模型获得
对于一个新加入的物品 i,可以通过 xTuyixuTyi估计用户 u 对物品 i 的兴趣,然后经过几个小时后,通过 pTuqipuTqi得到更准确的预测值。
与基于邻域的方法相比的优缺点: