2021人工智能领域新星创作者,带你从入门到精通,该博客每天更新,逐渐完善推荐系统各个知识体系的文章,帮助大家更高效学习。
1.隐语义模型与矩阵分解
对于推荐系统来说,如果使用协同过滤算法的话,一般是两种方式:UserCF、ItemCF,两种方式都是基于用户物品评分表(用户与物品之间的交互情况)的相似性进行计算。
- 对于UserCF,我们需要先找到与目标用户相似的群体,然后给目标用户推荐这些群体用户感兴趣的物品
- 对于ItemCF,我们需要找到和目标用户已经看过的物品相似的物品,然后利用其余用户对其的打分进行推荐
但是这两种方式会存在一些问题就是,处理稀疏矩阵的能力较弱,因为我们用户物品交互表存在大量空值,例如个别用户不会买所有的物品,每种物品也不会被所有用户光顾,在实际生活中,每个人购买的物品有限,而仓库中物品很多,如果采用这种方式,那么矩阵是稀疏的,在计算相似度的时候会出现大量的0,导致计算得到的相似度不精确。
所以为了使协同过滤能够更好的处理稀疏矩阵问题,增强泛化能力,衍生出了一种新的技术——矩阵分解模型(Matrix Factorization)或者也可以叫做隐语义模型。
协同过滤的两个主要方式分别是近邻模式、隐语义模型,基于用户和物品的UserCF和ItemCF就是近邻模式,因为需要计算与待评估事物最相近的相似度,而隐语义模型利用的就是矩阵分解技术,听名字就是要将我们的评分矩阵进行分解。
隐语义模型就是在协同过滤共现矩阵的基础上,使用更加稠密的隐向量来表示用户和物品,进而挖掘物品和用户之间更加深层的隐藏特征,这在一定程度上可以弥补协同过滤模型处理稀疏矩阵能力不足的问题。
2.隐语义模型(Latent Factor Model)
隐语义现在被广泛用到NLP中,像机器翻译,或者语义分析这些,用于找到文本之间潜在的隐含语义,比如说像现在的智能翻译,首先模型会检索整个语句,不可能是进行顺序翻译,而是需要先检索整个语句,挖掘不同位置单词或者语法的潜在含义,然后进行翻译。
那么隐语义模型对于推荐是怎样发挥作用呢?
它的核心思想就是挖掘物品和用户的隐含特征(latent factor),然后利用挖掘到的隐藏特征来联系用户的兴趣爱好与物品,就是基于用户的事务行为找出该用户潜在的一些特征,然后基于这些特征对事务进行聚类,然后将物品进行划分给兴趣一致的用户,这样说可能有点难懂。
举个例子:比如说用户A经常喜欢听摇滚、吉他伴奏的、汪峰的歌曲,那么之后我们就会基于这三个特征对物品进行分类,只要有一首歌符合这个特征,我们就认为用户A也会喜欢这首歌曲,然后将其推荐给用户A。
那么就是说我们利用了三个特征(摇滚、吉他伴奏的、汪峰)将用户和不同歌曲进行关联,当然这里我们是以0-1讨论的,只讨论是与不是,真实情况我们是会对每首歌按照这三个特征进行打分的,就是这首歌曲符合该特征的程度。
所以此时就需要维护两个矩阵,分别用户保存用户对每个特征或者兴趣的喜爱程度,另外一个用于保存每首歌曲符合其特征的程度分数。
- 潜在因子——用户矩阵Q
每一行代表不同的用户对不同兴趣或者特征的偏爱程度,越接近1说明越喜欢
- 潜在因子——音乐矩阵P
该表用户维护不同音乐符合不同特征的程度,越接近1说明这首歌曲越符合这个性质
那么现在我们应该如果利用这两张表计算每个用户对不同音乐的喜爱程度呢?
表1代表用户对不同兴趣的偏爱程度,越大说明越喜欢,表2代表歌曲对不同兴趣口味的符合程度,越大说明越符合,那么显然,我们可以利用它们两个的乘积作为最终用户对该音乐的喜爱程度。
比如针对这个表格:
张三对音乐A的喜爱得分 = 0.6 * 0.9 + 0.8 * 0.1 + 0.1 * 0.2 + 0.1 * 0.4 + 0.7 * 0 = 0.69
按照这个计算方式, 每个用户对每首歌其实都可以得到这样的分数, 最后就得到了我们的评分矩阵:
对于那些红色的数据就是该用户之前没有对其打过分,我们利用隐向量计算得到的。
说白了小清新、重口味就是我们挖掘到的隐特征,用来联系用户与歌曲之间的关系,显然如果我们的列越多,即挖掘到的隐特征越多我们能够表达的信息也越多,但是在实际问题中,这个隐特征是很难人为定义的,这也就是为什么叫做隐特征,因为它是隐含的信息,而且就算我们人为定义了隐特征,但它未必能够真实表示用户与音乐之间的联系。
而且现在还面临一个问题就是真实情况我们是没有上述两个矩阵的,我们只有协同过滤共现矩阵(即用户物品评分矩阵),而且该矩阵还是稀疏矩阵,存在大量物品与用户无交互的情况。
我们想到的解决问题就是去填充,显然是不现实的,一是真实情况数据量太大,二是如果利用物品或者用户相似性去填充矩阵会出现长尾现象,长尾现象就是一种分布,对于正态分布是中间多两头少,长尾是一头少,尾巴特别长,就是分布不均衡,在推荐领域就是会导致热门的物品一直被推荐,而冷门的物品由于长尾评分低,一直不能被推荐。
所以我们采用一种新的解决方式就是我们开头提出的矩阵分解(Matric Factorization),矩阵分解模型就是想办法基于协同过滤共现矩阵去获得那两个隐特征矩阵,就是将这个矩阵分解成两个矩阵P和Q乘积的形式,之后我们就可以利用这两个矩阵的乘积进行预测某个用户对某个物品的评分,然后基于评分去推荐。
3.矩阵分解算法的原理
上面说到,我们的目标就是根据评分矩阵去分解获得用户矩阵Q和物品矩阵P
矩阵分解就是将m * n维的评分矩阵分解成m * k维的用户矩阵U和k * n维的物品矩阵V相乘的形式。
其中的m代表用户数量,n代表物品数量,k就是隐特征的个数,这个k可以人工来定,也可使使用模型自己去学,当k定到一定程度时,人是无法解释隐特征的,我们会不知道它的具体含义,我们的k值越大,说明待挖掘的特征数越多,那么矩阵的表达能力就是越强,说白了就是把用户的兴趣和物品的分类划分的更加具体。
这其实和卷积识别图像是一个道理,我们的卷积核越大,通道数越多,那么我们对图片捕捉到的信息就会越多,参数对应也就会越多。
当我们分解完之后,我们需要计算不同用户对不同物品的评分只需要将两个矩阵进行相乘即可,即:
其中R:m * n , P:m * k ,Q:n * k
如果需要计算某个用户u对某个物品i的评分,只需要计算:
就是两个列向量做内积操作。
4.矩阵分解算法的求解
那么到底如何才能将评分矩阵进行分解呢?
主成分分析利用到了奇异值分解(SVD)进行分解特征矩阵,那么这里我们可不可以使用SVD进行分解呢?
答案是不行的,因为对于我们的评分矩阵是稀疏的,存在大量用户和物品无交互的情况,所以我们在使用SVD之前需要进行填充,其次是SVD的计算复杂度非常高,需要计算矩阵的特征值,而且当维度较高时,计算会非常复杂。
那么对于矩阵分解还有一种方式就是特征值分解,在这里也是显然不行的,因为使用特征值分解的前提要求是矩阵必须是方阵,这个要求对于我们的评分矩阵显然一般情况是不能够满足的。
那么应如何分解呢?
其实这个和神经网络的反向传播很像,我们定义一个优化函数,然后进行优化,那么我们就想办法将我们矩阵分解转化成一个优化问题,然后使用随机梯度下降进行求解。
2006年的Netflix Prize之后, Simon Funk公布了一个矩阵分解算法叫做Funk-SVD, 后来被Netflix Prize的冠军Koren称为Latent Factor Model(LFM)。 Funk-SVD的思想很简单:把求解上面两个矩阵的参数问题转换成一个最优化问题, 可以通过训练集里面的观察值利用最小化来学习用户矩阵和物品矩阵。
我们之前说到可以用用户矩阵与物品矩阵的乘积作为最终评分,那么现在是没有这个矩阵,那么我们刚开始可以随机初始化一个,里面随机赋些值,然后真实值与初始化矩阵得到的评分会有误差,因为我们这两个矩阵是随机初始化的最终计算结果是肯定不准的,那么就会产生一个误差:
那么此时就可以利用所有用户对所有物品的误差平方和作为优化函数:
现在有了可以评估精度的函数了,此时我们就可以利用最优化的算法进行求解其中的参数使其最小化:
对于这种优化函数,我们一般采用的是随机梯度下降(stochastic gradient descent),所以此时我们需要知道我们需要优化的参数的导数:
所以我们最终得到的参数更新公式为:
然后就可以基于梯度下降求其最优解,就可以获得分解后的矩阵了,因为我们求解的参数分别是两个矩阵的列向量。
这里没有考虑正则化,如果我们的数据过少或者说要防止过拟合,我们还需要对参数进行惩罚使用正则化。
5.优化函数的修改
上面我们已经获得了优化方程以及梯度更新公式,然后可以使用梯度下降法进行求解,但是此时会存在问题,结果可能有所偏差。
原因是有一些因素还没有考虑到,我们只是考虑用户矩阵和物品矩阵,这两个矩阵分别代表用户、物品与那些隐特征之间的联系,没有考虑到一些个人或者物品自身的一些影响。
比如说现在长津湖电影是非常火的,那么它的评分一定是很高的,但是它不一定都与用户有关系,一定程度上有它自身的因素影响,比如说里面的演员很出名或者上映时间等,这些与用户是没有关系的。
再比如一个用户是比较批判的,不管他观看什么类型的电影最终给出的评分都是比较低的,这个与电影就没什么关系了,单纯是个人因素影响。
所以针对这些问题,只考虑两个矩阵显然是不科学的,还需要在原来基础上加入一些偏置项来消除用户和物品打分的偏差,即:
这个预测公式加入了3项偏置μ , b u , b i 作用如下:
- μ \muμ: 训练集中所有记录的评分的全局平均数。 在不同网站中, 因为网站定位和销售物品不同, 网站的整体评分分布也会显示差异。 比如有的网站中用户就喜欢打高分, 有的网站中用户就喜欢打低分。 而全局平均数可以表示网站本身对用户评分的影响。
- b u b_ubu: 用户偏差系数, 可以使用用户u uu给出的所有评分的均值, 也可以当做训练参数。 这一项表示了用户的评分习惯中和物品没有关系的那种因素。 比如有些用户比较苛刻, 对什么东西要求很高, 那么他评分就会偏低, 而有些用户比较宽容, 对什么东西都觉得不错, 那么评分就偏高
- b i b_ibi: 物品偏差系数, 可以使用物品i ii收到的所有评分的均值, 也可以当做训练参数。 这一项表示了物品接受的评分中和用户没有关系的因素。 比如有些物品本身质量就很高, 因此获得的评分相对比较高, 有的物品本身质量很差, 因此获得的评分相对较低。
加入偏置项后的优化函数为:
对于新加入的偏置项的梯度为:
参数更新公式为: