LFM法实现的user item推荐系统

本文介绍了LFM(latent factor model)方法在推荐系统中的应用,包括LFM模型的理论基础、参数计算及优化过程。通过随机梯度下降算法优化损失函数,并讨论了初始化矩阵P和Q的方法。此外,还提到了K-Means聚类算法在数据预处理中的作用,以及在实际代码实现中遇到的问题和解决方案,如参数选择、过拟合等。最终,文章展示了代码运行结果和评估指标,强调了迭代过程中的手动干预以避免过拟合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

所有源码都在github上(https://github.com/seasonyao/recommended-system

代码环境:windows环境下python3.5,安装numpy和sklearn即可

源码、数据、结果:https://download.youkuaiyun.com/download/codes_first/10741150

各个读入文件的格式如下:

               

一、代码理论模型(参考书本《推荐系统实践》以及《机器学习》中理论内容,可跳过看后文具体思路和实现)

 

1.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后,
 

1.    我们不需要关心分类的角度,结果都是基于用户行为统计自动聚类的,全凭数据自己说了算。

2.    不需要关心分类粒度的问题,通过设置LFM的最终分类数就可控制粒度,分类数越大,粒度约细。

3.    对于一个item,并不是明确的划分到某一类,而是计算其属于每一类的概率,是一种标准的软分类。

4.    对于一个user,我们可以得到他对于每一类的兴趣度,而不是只关心可见列表中的那几个类。

5.    对于每一个class,我们可以得到类中每个item的权重,越能代表这个类的item,权重越高。

那么,接下去的问题就是如何计算矩阵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。损失函数如下所示:

上式中的是用来防止过拟合的正则化项,λ需要根据具体应用场景反复实验得到。损失函数的优化使用随机梯度下降算法:

 

1.    通过求参数PUK和QKI的偏导确定最快的下降方向;

2.    迭代计算不断优化参数(迭代次数事先人为设置),直到参数收敛。

其中,α是学习速率,α越大,迭代下降的越快。α和λ一样,也需要根据实际的应用场景反复实验得到。

 

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

 

2.Kmeans

K-Means算法的基本思想是初始随机给定K个簇中心,按照最邻近原则把待分类样本点分到各个簇。然后按平均法重新计算各个簇的质心,从而确定新的簇心。一直迭代,直到簇心的移动距离小于某个给定的值。

K-Means聚类算法主要分为三个步骤:
(1)第一步是为待聚类的点寻找聚类中心
(2)第二步是计算每个点到聚类中心的距离,将每个点聚类到离该点最近的聚类中去
(3)第三步是计算每个聚类中所有点的坐标平均值,并将这个平均值作为新的聚类中心
(4)反复执行(2)、(3),直到聚类中心不再进行大范围移动或者聚类次数达到要求为止

 

 

 

二、思路分析和遇到的问题

 

在开始正式讲代码之前,先来说说对几个细节问题的解决思路:

1.根据数据集初始化P和Q矩阵

这个初始化其实耗费了巨量的写代码时间,我的思路是

(1)对于P矩阵,对每一个用户计算其自己评分的平均值,然后用户对每个class的评分就以平均值为基础进行正态分布的随机值取值。

 

(2)对于Q的初始化前前后后做了很多工作:一开始就是以所有评分的平均值进行正态随机值(显然这和理论不符合,理论上Q是概率矩阵,也就是某个item所有class加起来要为1,但一开始就先简单赋予初值了)。后来结合itemAtrribute的文件,首先对这个文件里的item进行聚类(使用kmean),对于聚类结果我的利用方式有两种:

(a)一种是根据聚类结果把item分为150个class(为什么是150后文有解释),那么对于Q矩阵的初始化就可以按照我们的理论进行初始化了:某个item根据聚类结果属于某个class(又出现在itemAttribute最好,没有也可以和150个中心点算距离得到类别),将这个class对应的数设为某个参数(需要实验,可以说取决于你的class聚类的可信度,可信度高就概率给的大接近1,低就小),当然还是进行正态处理得到p,对于这个item其他class的值,则是(1-p)/149再分别进行正态处理,为了保证和为1最后那个p得重新赋值1-sum(其他)。

(b)第二种想法其实相当于增加数据集,根据聚类结果可以将一些同class的item在相同user那的评分给个差不多的值(同样正态处理࿰

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值