fourierr的博客

越过高山

隐语义模型(简介)

隐语义模型LFM和LSI,LDA,Topic Model其实都属于隐含语义分析技术,是一类概念,他们在本质上是相通的,都是找出潜在的主题或分类。这些技术一开始都是在文本挖掘领域中提出来的,近些年它们也被不断应用到其他领域中,并得到了不错的应用效果。比如,在推荐系统中它能够基于用户的行为对item进行自动聚类,也就是把item划分到不同类别/主题,这些主题/类别可以理解为用户的兴趣。

对于一个用户来说,他们可能有不同的兴趣。就以作者举的豆瓣书单的例子来说,用户A会关注数学,历史,计算机方面的书,用户B喜欢机器学习,编程语言,离散数学方面的书, 用户C喜欢大师Knuth, Jiawei Han等人的著作。那我们在推荐的时候,肯定是向用户推荐他感兴趣的类别下的图书。那么前提是我们要对所有item(图书)进行分类。那如何分呢?大家注意到没有,分类标准这个东西是因人而异的,每个用户的想法都不一样。拿B用户来说,他喜欢的三个类别其实都可以算作是计算机方面的书籍,也就是说B的分类粒度要比A小;拿离散数学来讲,他既可以算作数学,也可当做计算机方面的类别,也就是说有些item不能简单的将其划归到确定的单一类别;拿C用户来说,他倾向的是书的作者,只看某几个特定作者的书,那么跟A,B相比它的分类角度就完全不同了。

对于一个用户,首先得到他的兴趣分类,然后从分类中挑选他可能喜欢的物品。这里要解决3个问题:

  • 如何给物品分类?
  • 如何确定用户对哪些类感兴趣,以及感兴趣的程度?
  • 对于一个给定的类,选择哪些属于这个类的物品推荐给用户,以及如何确定这些物品在该类中的权重?
LFM解决这些问题的方法:
  • 根据用户的行为实现物品的自动聚类。如果2个物品被很多用户同时喜欢,那么他们属于一个隐类的概率很大。
  • 用户的兴趣通过用户的行为统计得到。
  • 在一个隐类中,如果一个物品被很多用户喜欢,那么它必定权重较大。
对于一个给定的用户行为数据集(数据集包含的是所有的user, 所有的item,以及每个user有过行为的item列表),使用LFM对其建模后,我们可以得到如下图所示的模型:(假设数据集中有3个user, 4个item, LFM建模的分类数为4)
 
其中,R矩阵是user-item兴趣度矩阵,矩阵值Rij表示的是user i 对item j的兴趣度;P是user-class兴趣度矩阵,Pij表示user i对class j的兴趣度;Q是item-class权重矩阵,Qij表示class i中item j的权重。
LFM通过如下公式计算用户u对物品i的兴趣度:

该公式中,是LFM模型的参数,表示矩阵P,Q中的值,需要估计它们的值。
要估计参数值,首先必须要有一个训练样本集,针对每个用户,选择用户的行为数据集作为正样本,正样本中都是用户发生过行为(喜欢)的物品,设=1。然后还需要选择一些数据作为负样本,选择负样本的原则:1、对于一个用户,要保证正、负样本的数量相近;2、对一个用户采样负样本时,要选择那些很热门、而用户没有发生行为的物品(很热门而用户却没有发生行为,更能说明用户不喜欢,冷门物品用户可能根本没有看到),负样本的物品,设=0。
LFM的损失函数仍然是平方差+正则项,如下:


其中,后面的正则项是为了防止过拟合,参数lamda通过实验可以得到。
通过最小化损失函数C来估计参数,采用梯度下降法来训练模型。
梯度下降法首先需要计算损失函数C的偏导数:



根据梯度下降法,需要将待估计参数pp沿着最速下降方向(梯度的反方向)向前推进,即:pp = pp - gradient,因此可以得到如下参数更新公式:
(k=1,2,……,K)
k=1,2,……,K

LFM模型训练就是参数不断更新直至收敛的过程,步骤如下:
1、初始化参数矩阵P、Q。给矩阵中待估计的参数设置一个初始值,可以为每个参数设置一个相同的概率均值。
2、初始化LFM模型的其他参数,包括:隐类的个数K,学习率的初始值,的初始值。其中,K的值不能太大,也不能太小,它控制的是粒度的粗细程度;的取值可以根据应用场景取一个合适的初始值。
3、模型训练。
    一次迭代的步骤:
          训练时,一个用户一个用户的依次迭代
    先从训练样本集中取用户u1的数据:

    从该数据集中依次选取一个,更新                                的值。N个item,要更新N次,要更新1次。
  
   再依次用其他用户u2,u3,…数据不断更新参数。 
   一次迭代完成后,得到一个P、Q,并得到损失函数C的一个值。

    不断的多次迭代,直至损失函数C的值收敛(或者,循环结束条件设为一个迭代次数N,迭代N次后结束)。


LFM的伪代码可以表示如下:

[python] view plaincopy


  1. def LFM(user_items, F, N, alpha, lambda):  

  2.     #初始化P,Q矩阵  

  3.     [P, Q] = InitModel(user_items, F)  

  4.     #开始迭代  

  5.     For step in range(0, N):  

  6.         #从数据集中依次取出user以及该user喜欢的iterms集  

  7.         for user, items in user_item.iterms():  

  8.             #随机抽样,为user抽取与items数量相当的负样本,并将正负样本合并,用于优化计算  

  9.             samples = RandSelectNegativeSamples(items)  

  10.             #依次获取item和user对该item的兴趣度  

  11.             for item, rui in samples.items():  

  12.                 #根据当前参数计算误差  

  13.                 eui = eui - Predict(user, item)  

  14.                 #优化参数  

  15.                 for f in range(0, F):  

  16.                     P[user][f] += alpha  (eui  Q[f][item] - lambda * P[user][f])  

  17.                     Q[f][item] += alpha  (eui  P[user][f] - lambda * Q[f][item])  

  18.         #每次迭代完后,都要降低学习速率。一开始的时候由于离最优值相差甚远,因此快速下降;  

  19.         #当优化到一定程度后,就需要放慢学习速率,慢慢的接近最优值。  

  20.         alpha *= 0.9  




阅读更多
上一篇隐语义模型(含代码)
下一篇各种聚类算法的介绍和比较
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭