隐语义模型LFM和LSI,LDA,Topic Model其实都属于隐含语义分析技术,是一类概念,他们在本质上是相通的,都是找出潜在的主题或分类。这些技术一开始都是在文本挖掘领域中提出来的,近些年它们也被不断应用到其他领域中,并得到了不错的应用效果。比如,在推荐系统中它能够基于用户的行为对item进行自动聚类,也就是把item划分到不同类别/主题,这些主题/类别可以理解为用户的兴趣。
对于一个用户来说,他们可能有不同的兴趣。就以作者举的豆瓣书单的例子来说,用户A会关注数学,历史,计算机方面的书,用户B喜欢机器学习,编程语言,离散数学方面的书, 用户C喜欢大师Knuth, Jiawei Han等人的著作。那我们在推荐的时候,肯定是向用户推荐他感兴趣的类别下的图书。那么前提是我们要对所有item(图书)进行分类。那如何分呢?大家注意到没有,分类标准这个东西是因人而异的,每个用户的想法都不一样。拿B用户来说,他喜欢的三个类别其实都可以算作是计算机方面的书籍,也就是说B的分类粒度要比A小;拿离散数学来讲,他既可以算作数学,也可当做计算机方面的类别,也就是说有些item不能简单的将其划归到确定的单一类别;拿C用户来说,他倾向的是书的作者,只看某几个特定作者的书,那么跟A,B相比它的分类角度就完全不同了。(举例来自《推荐系统实践》项亮著)
此外我们还需要注意的两个问题:
下面我们就来看看LFM是如何解决上面的问题的?对于一个给定的用户行为数据集(数据集包含的是所有的user, 所有的item,以及每个user有过行为的item列表),使用LFM对其建模后,我们可以得到如下图所示的模型:(假设数据集中有3个user, 4个item, LFM建模的分类数为4)
R矩阵是user-item矩阵,矩阵值Rij表示的是user i 对item j的兴趣度,这正是我们要求的值。对于一个user来说,当计算出他对所有item的兴趣度后,就可以进行排序并作出推荐。LFM算法从数据集中抽取出若干主题,作为user和item之间连接的桥梁,将R矩阵表示为P矩阵和Q矩阵相乘。其中P矩阵是user-class矩阵,矩阵值Pij表示的是user i对class j的兴趣度;Q矩阵式class-item矩阵,矩阵值Qij表示的是item j在class i中的权重,权重越高越能作为该类的代表。所以LFM根据如下公式来计算用户U对物品I的兴趣度
我们发现使用LFM后,
那么,接下去的问题就是如何计算矩阵P和矩阵Q中参数值。一般做法就是最优化损失函数来求参数。在定义损失函数之前,我们需要准备一下数据集并对兴趣度的取值做一说明。数据集应该包含所有的user和他们有过行为的(也就是喜欢)的item。所有的这些item构成了一个item全集。对于每个user来说,我们把他有过行为的item称为正样本,规定兴趣度RUI=1,此外我们还需要从item全集中随机抽样,选取与正样本数量相当的样本作为负样本,规定兴趣度为RUI=0。因此,兴趣的取值范围为[0,1]。采样之后原有的数据集得到扩充,得到一个新的user-item集K={(U,I)},其中如果(U,I)是正样本,则RUI=1,否则RUI=0。损失函数如下所示:
损失函数的优化使用随机梯度下降算法:
通俗理解:LFM的实质是,假设存在K个因素影响模型的预测值。通过两组向量(一组一维行向量,一组一维列向量),其中每个向量有K个元素,两个向量对应相乘为一个数值,如第一个行向量与第一个列向量乘积代表模型对原user-item矩阵第一行第一列的值的预测(1或0)。则推广至全部的向量,对应相乘恰好对应着user-item矩阵的m行n列数值。通过随机梯度下降的迭代,不断更新这些向量的K个元素,使得loss最小。则这个模型的预测贴合数据。
综上所述,执行LFM需要:
如何初始化P和Q矩阵?
目前一般采用标准正态分布随机生成
如何确定这4个参数?
经验之谈:
伪代码:
def LFM(user_items, F, N, alpha, lambda):
#初始化P,Q矩阵
[P, Q] = InitModel(user_items, F)
#开始迭代
For step in range(0, N):
#从数据集中依次取出user以及该user喜欢的iterms集
for user, items in user_item.iterms():
#随机抽样,为user抽取与items数量相当的负样本,并将正负样本合并,用于优化计算
samples = RandSelectNegativeSamples(items)
#依次获取item和user对该item的兴趣度
for item, rui in samples.items():
#根据当前参数计算误差
eui = eui - Predict(user, item)
#优化参数
for f in range(0, F):
P[user][f] += alpha * (eui * Q[f][item] - lambda * P[user][f])
Q[f][item] += alpha * (eui * P[user][f] - lambda * Q[f][item])
#每次迭代完后,都要降低学习速率。一开始的时候由于离最优值相差甚远,因此快速下降;
#当优化到一定程度后,就需要放慢学习速率,慢慢的接近最优值。
alpha *= 0.9
RS实战2——LFM算法实践(基于movielens数据集)
理论部分参考来源:Top-N推荐