前言
主要讲的是一些基础且常用的推荐算法。
一、常用推荐算法分类
1、基于人口统计学的推荐算法
- 基于人口统计学的推荐机制(Demographic-based Recommendation)是一种最易于实现的推荐方法,它只是简单的根据系统用户的基本信息发现用户的相关程度,然后将相似用户喜爱的其他物品推荐给当前用户。
- 对于没有明确含义的用户信息(比如登录时间、地域等上下文信息),可以通过聚类等手段,给用户打上分类标签。
- 对于特定标签的用户,又可以根据预设的规则(知识)或者模型,推荐出对应的物品。
- 用户信息标签化的过程一般又称为
用户画像
(User Profiling)。
1.1、用户画像
- 用户画像就是企业通过收集与分析消费者社会属性、生活习惯、消费行为等主要信息的数据之后,完美地抽象出一个用户的商业全貌,是企业应用
大数据技术
的基本方式。 - 用户画像为企业提供了足够的信息基础,能够帮助企业快速找到精准用户群体以及用户需求等更为广泛的反馈信息。
- 作为大数据的根基,它完美地抽象出一个用户的信息全貌,为进一步精准、快速地分析用户行为习惯、消费习惯等重要信息,提供了足够的数据基础。
示例:
2、基于内容的推荐算法
- 基于内容的推荐算法(Content-based Recommendations,CB)根据推荐物品或内容的元数据,发现物品的相关性,再基于用户过去的喜好记录,为用户推荐相似的物品。
- 通过抽取物品内在或者外在的
特征值
,实现相似度计算。- 比如一个电影,由导演、演员、用户标签UGC、用户评论、时长、风格等等,都可以算是特征。
- 将
用户个人信息的特征
(基于喜好记录或是预设兴趣标签),和物品的特征
相匹配,就能得到用户对物品感兴趣的程度。- 在一些电影、音乐、图书的社交网站有很成功的应用,有些网站还请专业人员对物品进行基因编码/打标签(PGC)。
- 对于物品的特征提取——打标签(tag)
- 专家标签(PGC)
- 用户自定义标签(UGC)
- 降维分析数据,提取隐语义标签(LFM)
- 对于文本信息的特征提取——关键词
- 分词、语义处理和情感分析(NLP)
- 潜在语义分析(LSA)
2.1、相似度计算
-
相似度的评判,可以用距离表示,而一般更常用的是“余弦相似度”。
-
-
欧氏距离:
d ( x , y ) = ∑ i ( x i − y i ) 2 d(x,y)=\sqrt{\displaystyle\sum_{i}(x_i-y_i)^2} d(x,y)=i∑(xi−yi)2 -
余弦相似度:
c o s θ = a ⋅ b ∥ a ∥ × ∥ b ∥ = ∑ i x i y i ∑ i x i 2 × ∑ i y i 2 cos\theta=\frac{a\cdot b}{\lVert{a}\rVert\times\lVert{b}\rVert}=\frac{\displaystyle\sum_{i}x_iy_i}{\sqrt{\displaystyle\sum_{i}x_i^2}\times\sqrt{\displaystyle\sum_{i}y_i^2}} cosθ=∥a∥×∥b∥a⋅b=i∑xi2×i∑yi2i∑xiyi
2.2、基于内容推荐系统的高层次结构
2.3、特征工程
- 特征:作为判断条件的一组输入变量,是做出判断的依据。
- 目标:判断和预测的目标,模型的输出变量,是特征所产生的结果。
- 特征(feature):数据中抽取出来的
对结果预测有用
的信息。 - 特征的个数就是数据的观测维度。
- 特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的
过程
。 - 特征工程一般包括特征清洗(采样、清洗异常样本),特征处理和特征选择。
- 特征按照不同的数据类型分类,有不同的特征处理方法:
- 数值型
- 类别型
- 时间型
- 统计型
2.3.1、数值型特征处理
-
用连续数值表示当前维度特征,通常会对数值型特征进行数学上的处理,主要做法是归一化和离散化。
-
归一化/幅度调整:
-
特征与特征之间应该是平等的,区别应该体现在特征内部。
-
例如房屋价格和住房面积的幅度是不同的,房屋价格可能在300000015000000(万)之间,而住房面积在40300(平方米)之间,那么明明是平等的两个特征,输入到相同的模型中后由于本身的幅值不同导致产生的效果不同,这是不合理的。
-
F e a t u r e n e w = F e a t u r e o l d F e a t u r e m a x − F e a t u r e m i n Feature_{new}=\frac{Feature_{old}}{Feature_{max}-Feature_{min}} Featurenew=Featuremax−FeatureminFeatureold
-
-
-
离散化:
- 将原始连续值切断,转化为离散值:
h θ ( x ) = g ( θ T x ) = 1 1 + e − θ T x h_{\theta}(x)=g({\theta}^Tx)=\frac{1}{1+e^{-{\theta}^Tx}} hθ(x)=g(θTx)=1+e−θTx1
让座问题:假设我们要训练一个模型判断在公交车上应不应该给一个人让座,按照常理,应该是给年龄很大和年龄很小的人让座。
对于以上让座问题中的年龄特征,对于一些模型,假设模型为 y = θ x y= θx y=θx,输入的x(年龄)对于最后的贡献是正/负相关的,即x越大越应该让座,但很明显让座问题中,年龄和是否让座不是严格的正相关或者负相关,这样只能兼顾年龄大的人,无法兼顾年龄大的人和年龄小的人。
对于让座问题,我们可以使用阈值将年龄进行分段,将一个age特征分为多个特征,将连续值离散化。如下图所示:
在电商中,每个人对于价格的喜好程度不同,但它不一定是严格的正相关或负相关,某些人可能就喜欢某一价格段内的商品。
-
离散化的两种方式:
- 等步长——简单但不一定有效
- 等频—— m i n − > 25 % − > 75 % − > m a x min->25\%->75\%->max min−>25%−>75%−>max
-
两种方法对比:
- 等频的离散化方法很精准,但需要每次都对数据分布进行一遍重新计算,因为昨天用户在淘宝上买东西的价格分布和今天不一定相同,因此昨天做等频的切分点可能并不适用,而线上最需要避免的就是不固定,需要现场计算,所以昨天训练出的模型今天不一定能使用。
- 等频不固定,但很精准,等步长是固定的,非常简单,因此两者在工业上都有应用。
- 将原始连续值切断,转化为离散值:
2.3.2、类别型特征处理
- 类别型数据本身没有大小关系,需要将它们编码为数字,但
它们之间不能有预先设定的大小关系
,因此既要做到公平,又要区分开它们,那么直接开辟多个空间。
One-Hot编码/哑变量:
One-Hot编码/哑变量所做的就是将类别型数据平行地展开,也就是说,经过One-Hot编码/哑变量后,这个特征的空间会膨胀。
2.3.3、时间型特征处理
- 时间型特征值既可以做连续值,又可以做离散值。
- 连续值
- 持续时间(网页浏览时长)
- 间隔时间(上一次购买/点击离现在的时间间隔)
- 离散值
- 一天中哪个时间段
- 一周中的星期几
- 一年中哪个月/星期
- 工作日/周末
2.3.4、统计型特征处理
- 加减平均: 商品价格高于平均价格多少,用户在某个品类下消费超过多少。
- 分位线: 商品属于售出商品价格的分位线处。
- 次序性: 商品处于热门商品第几位。
- 比例类: 电商中商品的好/中/差评比例。
2.4、推荐系统常见反馈数据
显式:可以直接体现出用户偏好。
隐式:需要经过后续分析才能得到用户的偏好。
3、基于UGC的推荐
-
用户用标签来描述对物品的看法,所以用户生成标签(UGC)是联系用户和物品的纽带,也是反应用户兴趣的重要数据源。
-
一个用户标签行为的数据集一般由一个三元组(用户、物品、标签)的集合表示,其中一条记录(u、i、b)表示用户u给物品i打上了标签b。
-
一个最简单的算法
-
统计每个用户最常用的标签;
-
对于每个标签,统计被打过这个标签次数最多的物品;
-
对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门的物品,推荐给他;
-
所以用户u对物品i的兴趣公式为
p ( u , i ) = ∑ b n u , b n b , i p(u,i)=\displaystyle\sum_b{n_{u,b}n_{b,i}} p(u,i)=b∑nu,bnb,i
其中, n u , b n_{u,b} nu,b是用户u打过标签b的次数, n b , i n_{b,i} nb,i是物品i被打过标签b的次数
-
3.1、基于UGC简单推荐的问题
- 简单算法中直接将
用户打出标签的次数
和物品得到的标签次数
相乘,可以简单地表现出用户对物品某个特征的兴趣。 - 这种方法倾向于给热门标签(谁都会给的标签,如“大片”、“搞笑”等)、热门物品(打标签人数最多)比较大的权重,如果一个热门物品同时对应着热门标签,那它就会“霸榜”,推荐的个性化、新颖度就会降低。
- 类似的问题,出现在新闻内容的关键字提取中,比如以下新闻中,哪个关键字应该获得更好的权重?
3.2、TF-IDF
-
词频-逆文档频率
(Term Frequency-Inverse Document Frequency,TF-IDF)是一种用于资讯检索与文本挖掘的常用加权技术。 -
TF-IDF是一种
统计
方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加
,但同时会随着它在语料库中出现的频率成反比下降
T F I D F = T F × I D F TFIDF=TF\times IDF TFIDF=TF×IDF -
TF-IDF的主要思想是: 如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
-
TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量和评级。
-
词频(Term Frequency,TF)
- 指的是某一个给定的词语在该文件中出现的频率,这个数字是对词数的归一化,以防止偏向更长的文件。(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否)
T F i , j = n i , j n ∗ , j TF_{i,j}=\frac{n_{i,j}}{n_{*,j}} TFi,j=n∗,jni,j
其中 T F i , j TF_{i,j} TFi,j表示词语i在文档j中出现的频率, n i , j n_{i,j} ni,j表示i在j中出现的次数, n ∗ , j n_{*,j} n∗,j表示文档j的总词数
- 指的是某一个给定的词语在该文件中出现的频率,这个数字是对词数的归一化,以防止偏向更长的文件。(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否)
-
逆向文件频率(Inverse Document Frequency,IDF)
- 是一个词语普遍重要性的度量,某一特定词语的IDF,可以由总文档数目除以包含该词语之文档的数目,再将得到的商取对数得到
I D F i = l o g ( N + 1 N i + 1 ) IDF_i=log(\frac{N+1}{N_i+1}) IDFi=log(Ni+1N+1)
其中 I D F i IDF_i IDFi表示词语i在文档集中的逆文档频率, N N N表示文档集中的文档总数, N i N_i Ni表示文档集中包含了词语i的文档数
- 是一个词语普遍重要性的度量,某一特定词语的IDF,可以由总文档数目除以包含该词语之文档的数目,再将得到的商取对数得到
3.2.1、TF-IDF示例代码
- 0、引入依赖
import numpy as np
import pandas as pd
- 1、定义数据和预处理
docA = 'The cat sat on my bed'
docB = 'The dog sat on my knees'
bowA = docA.split(' ')
bowB = docB.split(' ')
# 构建词库
wordSet = set(bowA).union(set(bowB))
wordSet
- 2、进行词数统计
# 用一个统计字典来保存词出现的次数
wordDictA = dict.fromkeys(wordSet, 0)
wordDictB = dict.fromkeys(wordSet, 0)
# 遍历文档,统计词数
for word in bowA:
wordDictA[word] += 1
for word in bowB:
wordDictB[word] += 1
pd.DataFrame([wordDictA, wordDictB])
- 3、计算词频TF
def computeTF(wordDict, bow):
# 用一个字典对象记录TF,把所有的词对应在bow文档里的tf都算出来
tfDict = {}
nbowCount = len(bow) # 总词数
for word, count in wordDict.items():
tfDict[word] = count / nbowCount
return tfDict
tfA = computeTF(wordDictA, bowA)
tfB = computeTF(wordDictB, bowB)
tfA
- 4、计算逆文档频率IDF
def computeIDF(wordDictList):
# 用一个字典对象保存IDF结果,每个词作为key,初始值为0
idfDict = dict.fromkeys(wordDictList[0], 0)
N = len(wordDictList)
import math
for wordDict in wordDictList:
# 遍历字典中的每个词汇
for word, count in wordDict.items():
if count > 0:
# 先把Ni增加1,存到idfDict
idfDict[word] += 1
# 已经得到所有词汇对应的Ni,现在根据公式把它替换成为最后的idf值
for word, ni in idfDict.items():
idfDict[word] = math.log10((N+1)/(ni+1))
return idfDict
idfs = computeIDF([wordDictA, wordDictB])
idfs
- 5、计算TF-IDF
def computeTFIDF(tf, idfs):
tfidf = {}
for word, tfval in tf.items():
tfidf[word] = tfval * idfs[word]
return tfidf
tfidfA = computeTFIDF(tfA, idfs)
tfidfB = computeTFIDF(tfB, idfs)
pd.DataFrame([tfidfA, tfidfB])
3.3、TF-IDF对基于UGC推荐的改进
p ( u , i ) = ∑ b n u , b n b , i p(u,i)=\displaystyle\sum_bn_{u,b}n_{b,i} p(u,i)=b∑nu,bnb,i
-
为了避免热门标签和热门物品获得更多的权重,我们需要对“热门”进行
惩罚
; -
借鉴TF-IDF的思想,以一个物品的所有标签作为“文档”,标签作为“词语”,从而计算标签的“词频”(在物品所有标签中的频率)和“逆文档频率”(在其他物品标签中普遍出现的频率);
-
由于“物品i的所有标签“ n ∗ , i n_{*,i} n∗,i应该对标签权重没有影响,而”所有标签总数“ N N N对于所有标签是一定的,所以这两项可以略去。在简单算法的基础上,直接加入对热门标签和热门物品的惩罚项:
p ( u , i ) = ∑ b n u , b l o g ( 1 + n b ( u ) ) n b , i l o g ( 1 + n i ( u ) ) p(u,i)=\displaystyle\sum_b{\frac{n_{u,b}}{log(1+n_b^{(u)})}}{\frac{n_{b,i}}{log(1+n_i^{(u)})}} p(u,i)=b∑log(1+nb(u))nu,blog(1+ni(u))nb,i
其中, n b ( u ) n_b^{(u)} nb(u)记录了标签b被多少个不同的用户使用过, n i ( u ) n_i^{(u)} ni(u)记录了物品i被多少个不同的用户打过标签
4、基于协同过滤的推荐算法
协同过滤(Collaborative Filtering,CF)
- 基于近邻的协同过滤
- 基于用户(User-CF)
- 基于物品(Item-CF)
- 基于模型的协同过滤
- 奇异值分解(SVD)
- 潜在语义分析(LSA)
- 支持向量机(SVM)
基于内容(CB)主要利用的是用户评价过的物品的
内容特征
,而CF方法还可以利用其他用户评分过的物品内容。
- CF可以解决CB的一些局限
物品内容不完全
或者难以获得
时,依然可以通过其他用户的反馈给出推荐;- CF基于用户之间对物品的
评价质量
,避免了CB仅依赖内容可能造成的对物品质量判断的干扰; - CF推荐
不受内容限制
,只要其他类似用户给出了对不同物品的兴趣,CF就可以给用户推荐出内容差异很大
(但有某种内在联系)的物品。
CF的缺点在于无法解决“冷启动”问题
,所谓“冷启动”,指的是网站建设初期由于缺乏用户数据,导致在该网站上运行的推荐系统做不到预期的效果。因此,在网站建设初期,主要是通过给物品打上标签,用一些CB推荐算法来收集用户数据,当用户数据收集的规模达到一定程度后,可以慢慢地渐变为CF推荐算法。
CF分为两类:基于近邻和基于模型。
4.1、基于近邻的推荐
基于近邻的推荐系统根据的是相同“口碑”准则。
是否应该给Cary推荐《泰坦尼克号》?
答案:由于C与A的数据相似(用户相似),因此可以认为C很有可能像A一样也喜欢泰坦尼克号,故将此电影推荐给C;再从基于物品的角度,泰坦尼克号的数据与阿甘正传相似,故C-泰坦尼克号的值应该也较高,因此应该给C推荐泰坦尼克号。
4.1.1、基于用户的协同过滤(User-CF)
- 基于用户的协同过滤推荐的基本原理是,根据所有用户对物品的
偏好
,发现与当前用户口味和偏好相似的“邻居”用户群
,并推荐近邻所偏好的物品; - 在一般应用中是采用计算
“K-近邻”的算法
,基于这K个邻居的历史偏好信息,为当前用户进行推荐。 - User-CF和基于人口统计学的推荐机制
- 两者都是计算
用户的相似度
,并基于相似的“邻居”用户群计算推荐; - 他们所
不同的是如何计算用户的相似度
,基于人口统计学的机制只考虑用户本身的特征
,而基于用户的协同过滤机制可以在用户的历史偏好
的数据上计算用户的相似度,它的基本假设是,喜欢类似物品的用户可能有相同或者相似的口味和偏好。
- 两者都是计算
4.1.2、基于物品的协同过滤
- 基于物品的协同过滤推荐的基本原理与基于用户的类似,只是使用所有用户对物品的偏好,发现物品和物品之间的相似度,然后根据用户的历史偏好信息,将类似的物品推荐给用户。
- Item-CF和CB的推荐
- 其实都是
基于物品相似度预测
推荐,只是相似度计算的方法不一样。前者是从用户历史的偏好推断,而后者是基于物品本身的属性特征信息。
- 其实都是
- 同样是协同过滤,在User-CF和Item-CF两个策略中应该如何选择?
- 电商、电影、音乐网站,用户数量远大于物品数量;
- 新闻网站,物品(新闻文本)数量可能大于用户数量。
- 选
量少的
,这样比较稳定
,效果可能会更好一些。
4.1.3、User-CF和Item-CF的比较
同样是协同过滤,在User-CF和Item-CF两个策略中应该如何选择?
- Item-CF应用场景
- Item-CF推荐机制是Amazon在基于用户的机制上改良的一种策略。因为在大部分的Web站点中,
物品的个数是远远小于用户的数量的
,而且物品的个数和相似度相对比较稳定
,同时基于物品的机制比基于用户的实时性更好一些
,所以Item-CF成为了目前推荐策略的主流
。
- Item-CF推荐机制是Amazon在基于用户的机制上改良的一种策略。因为在大部分的Web站点中,
- User-CF应用场景
- 设想一下,在一些新闻推荐系统中,也许物品——也就是
新闻的个数可能大于用户的个数
,而且新闻的更新程度也很快,所以它的相似度依然不稳定,这时用User-CF可能效果更好。
- 设想一下,在一些新闻推荐系统中,也许物品——也就是
- 所以,推荐策略的选择其实和
具体的应用场景
有很大的关系。
4.1.4、基于协同过滤的推荐的优缺点
- 优点:
- 它不需要对物品或者用户进行严格的建模,而且不要求对物品特征的描述是机器可理解的,所以这种方法也是
领域无关
的; - 这种方法计算出来的推荐是
开放
的,可以共用他人的经验
,很好的支持用户发现潜在的兴趣偏好
。
- 它不需要对物品或者用户进行严格的建模,而且不要求对物品特征的描述是机器可理解的,所以这种方法也是
- 存在的问题:
- 方法的核心是基于
历史数据
,所以对新物品和新用户都有“冷启动”
的问题; - 推荐的效果依赖于用户历史偏好数据的多少和准确性;
- 在大部分的实现中,用户历史偏好是用
稀疏矩阵
进行存储的,而稀疏矩阵上的计算有些明显的问题,包括可能少部分人的错误偏好会对推荐的准确度有很大的影响等等; - 对于一些特殊品味的用户不能给予很好的推荐。
- 方法的核心是基于
4.2、基于模型的协同过滤思想
- 基本思想
- 用户具有一定的特征,决定着他的偏好选择;
- 物品具有一定的特征,影响着用户是否选择它;
- 用户之所以选择某一个商品,是因为用户特征与物品特征相互
匹配
。
- 基于这种思想,
模型的建立
相当于从行为数据中提取特征,给用户和物品同时
打上“标签”;这和基于人口统计学的用户标签、基于内容方法的物品标签本质是一样的,都是特征的提取和匹配。 - 有显性特征时(比如用户标签、物品分类标签)我们可以直接匹配做出推荐;没有时,可以根据已有的偏好数据,去发现出隐藏的特征,这需要用到
隐语义模型(LFM)
。
基于模型的协同过滤推荐,就是基于样本的用户偏好信息,训练一个推荐模型,然后根据实时的用户喜好的信息进行预测新物品的得分,计算推荐。
4.2.1、基于模型和基于近邻的比较
基于近邻的推荐和基于模型的推荐
- 基于近邻的推荐是在预测时直接使用已有的用户偏好数据,通过近邻数据来预测对新物品的偏好(类似分类)
- 而基于模型的方法,是要使用这些偏好数据来训练模型,找到内在规律,再用模型来做
预测
(类似回归)
4.2.2、隐语义模型(LFM)
隐语义模型:训练模型时,可以基于标签内容来提取物品特征,也可以让模型去发掘物品的潜在特征,这样的模型被称为隐语义模型(Latent Factor Model,LFM)
- 用隐语义模型来进行协同过滤的目标
- 揭示隐藏的特征,这些特征能够解释为什么给出对应的预测评分;
- 这类特征可能是无法直接用语言解释描述的,事实上我们并不需要知道,类似“玄学”。
- 通过矩阵分解进行降维分析
- 协同过滤算法非常依赖历史数据,而一般的推荐系统中,偏好数据又往往是稀疏的,这就需要对原始数据做
降维处理
; - 分解之后的
矩阵
,就代表了用户和物品的隐藏特征。
- 协同过滤算法非常依赖历史数据,而一般的推荐系统中,偏好数据又往往是稀疏的,这就需要对原始数据做
- 隐语义模型的实例
- 基于概率的隐语义分析(pLSA)
- 隐式迪利克雷分布模型(LDA)
- 矩阵因子分解模型(基于奇异值分解的模型,SVD)
4.2.2.1、LFM降维方法——矩阵因子分解(简介)
假设用户物品评分矩阵为R,现在有m个用户,n个物品。
我们想要发现k个隐类,我们的任务就是找到两个矩阵P和Q,使这两个矩阵的乘积近似等于R,即将用户物品评分矩阵R分解成为两个低维矩阵相乘:
R ^ m × n = P k × m T × Q k × n ≈ R \hat{R}_{m\times n}=P_{k\times m}^T\times Q_{k\times n}\approx R R^m×n=Pk×mT×Qk×n≈R
具体示图如下:
矩阵因子分解
4.2.2.2、LFM的进一步理解
我们可以认为,用户之所以给电影打出这样的分数,是有内在原因的,我们可以挖掘出影响用户打分的隐藏因素,今儿根据未评分电影与这些隐藏因素的关联度,决定此未评分电影的预测评分。
应该有一些隐藏的因素影响用户的打分。比如电影:演员、题材、年代、甚至不一定是人直接可以理解的隐藏因子。
找到隐藏因子,可以对user和item进行关联
(找到是由于什么使得user喜欢/不喜欢此item,什么会决定user喜欢/不喜欢此item),就可以推测用户是否会喜欢某一部未看过的电影。
对于用户看过的电影,会有相应的打分,但一个用户不可能看过所有的电影,对于用户没有看过的电影是没有评分的,因此用户评分矩阵大部分项都是空的,是一个稀疏矩阵。
如果我们能够根据用户给已有电影的打分推测出用户会给没有看过的电影的打分,那么就可以根据预测结果给用户推荐他可能打高分的电影。
4.2.2.3、矩阵因子分解
现在做一个一般性分析
-
一个 m × n m\times n m×n的打分矩阵R可以用两个小矩阵 P m × k P_{m\times k} Pm×k和 Q k × n Q_{k\times n} Qk×n的乘积 R ^ \hat{R} R^来近似:
R ^ u i = P u ⋅ Q i = ∑ k = 1 K P u k ⋅ Q k i \hat{R}_{ui}=P_{u}\cdot Q_{i}=\displaystyle\sum_{k=1}^KP_{uk}\cdot Q_{ki} R^ui=Pu⋅Qi=k=1∑KPuk⋅Qki
-
得到 P m × k P_{m\times k} Pm×k和 Q k × n Q_{k\times n} Qk×n的乘积 R ^ \hat{R} R^不再是稀疏的,之前R中没有的项也可以由P、Q的乘积算出,这就得到了一个预测评分矩阵
-
如果得到的预测评分矩阵 R ^ \hat{R} R^与原评分矩阵R在已知评分位置上的值都近似,那么我们认为它们在预测位置上的值也是近似的
4.2.2.4、模型的求解——损失函数
现在的问题:怎样得到这样的分解方式 R ^ = P × Q \hat{R}=P\times Q R^=P×Q呢?
矩阵分解得到的预测评分矩阵
R
^
\hat{R}
R^与原评分矩阵R在已知的评分项上可能会有误差,我们的目标是找到一个最好的分解方式,让分解之后的预测评分矩阵总误差最小
。
损失函数
- 选择平方损失函数,并且加入正则化项,以防
过拟合
C = ∑ ( u , i ) ∈ R 0 ( R u i − R ^ u i ) 2 + R e g = ∑ ( u , i ) ∈ R 0 ( R u i − P u ⋅ Q i ) 2 + λ ∑ u ∥ P u ∥ 2 + λ ∑ i ∥ Q i ∥ 2 C=\displaystyle\sum_{(u,i)\in R_0}(R_{ui}-\hat{R}_{ui})^2+Reg=\displaystyle\sum_{(u,i)\in R_0}(R_{ui}-P_u\cdot Q_i)^2+\lambda\displaystyle\sum_{u}{\lVert P_u\rVert}^2+\lambda\displaystyle\sum_{i}{\lVert Q_i\rVert}^2 C=(u,i)∈R0∑(Rui−R^ui)2+Reg=(u,i)∈R0∑(Rui−Pu⋅Qi)2+λu∑∥Pu∥2+λi∑∥Qi∥2
其中 λ ∑ u ∥ P u ∥ 2 + λ ∑ i ∥ Q i ∥ 2 \lambda\displaystyle\sum_{u}{\lVert P_u\rVert}^2+\lambda\displaystyle\sum_{i}{\lVert Q_i\rVert}^2 λu∑∥Pu∥2+λi∑∥Qi∥2是正则项, λ \lambda λ一般通过交叉验证
得到
4.2.2.5、模型的求解算法——ALS
现在,矩阵因子分解的问题已经转化成了一个标准的优化问题,需要求解P、Q,是目标损失函数取最小值。
最小化过程的求解,一般采用随机梯度下降算法或者交替最小二乘法来实现。
交替最小二乘法(Alternating Least Squares,ALS)
-
ALS的思想是,由于两个矩阵P和Q都未知,且通过矩阵乘法
耦合
在一起,为了使它们解耦
,可以先固定Q,把P当作变量,通过损失函数最小化求出P,这就是一个经典的最小二乘问题
;再反过来固定求得的P,把Q当作变量,求解出Q;如此交替执行,直到误差满足阈值条件,或者到达迭代上限。 -
ALS算法具体过程如下:
- 为Q指定一个初值 Q 0 Q_0 Q0,可以是0或者全局平均值;
- 固定当前 Q 0 Q_0 Q0值,求解 P 0 P_0 P0;
- 固定当前 P 0 P_0 P0值,求解 Q 1 Q_1 Q1;
- 固定当前 Q 1 Q_1 Q1值,求解 P 1 P_1 P1;
- (重复以上过程);
- 直到损失函数的值C收敛,迭代结束。
-
ALS算法精确求解过程:
-
以固定Q,求解P为例;
-
由于每一个用户u都是相互独立的,当Q固定时,用户特征向量 P u P_u Pu应该取得的值与其它用户特征向量无关,所以每一个 P u P_u Pu都可以单独求解;
-
优化目标 min P , Q C \displaystyle\min_{P,Q}C P,QminC可转化为
min P [ ∑ u , i ( R u i − P u ⋅ Q i ) 2 + λ ∑ u ∥ P u ∥ 2 ] = ∑ u min P [ ∑ i ( R u i − P u ⋅ Q i ) 2 + λ ∥ P u ∥ 2 ] \displaystyle\min_P[\displaystyle\sum_{u,i}(R_{ui}-P_u\cdot Q_i)^2+\lambda\displaystyle\sum_{u}{\lVert P_u\rVert}^2]=\displaystyle\sum_{u}\displaystyle\min_P[\displaystyle\sum_{i}(R_{ui}-P_u\cdot Q_i)^2+\lambda{\lVert P_u\rVert}^2] Pmin[u,i∑(Rui−Pu⋅Qi)2+λu∑∥Pu∥2]=u∑Pmin[i∑(Rui−Pu⋅Qi)2+λ∥Pu∥2] -
令
L u ( P u ) = ∑ i ( R u i − P u ⋅ Q i ) 2 + λ ∥ P u ∥ 2 L_u(P_u)=\displaystyle\sum_{i}(R_{ui}-P_u\cdot Q_i)^2+\lambda{\lVert P_u\rVert}^2 Lu(Pu)=i∑(Rui−Pu⋅Qi)2+λ∥Pu∥2 -
那么我们的目标变成了:求每一个用户特征向量 P − u P-u P−u,使得 L u ( P u ) L_u(P_u) Lu(Pu)取得最小值
-
L u L_u Lu对 P u P_u Pu求偏导:
ð L u ð P u = ð [ ∑ i ( R u i − P u ⋅ Q i ) 2 + λ ∥ P u ∥ 2 ] ð P u = ∑ i 2 ( P u Q i − R u i ) Q i + 2 λ P u T = 2 ( ∑ i P u Q i Q i − ∑ i R u i Q i + λ P u T ) \frac{\eth L_u}{\eth P_u} =\frac{\eth[\displaystyle\sum_{i}(R_{ui}-P_u\cdot Q_i)^2+\lambda{\lVert P_u\rVert}^2]}{\eth P_u}=\displaystyle\sum_{i}2(P_uQ_i-R_{ui})Q_i+2\lambda P_u^T =2(\displaystyle\sum_{i}P_uQ_iQ_i-\displaystyle\sum_{i}R_{ui}Q_i+\lambda P_u^T) ðPuðLu=ðPuð[i∑(Rui−Pu⋅Qi)2+λ∥Pu∥2]=i∑2(PuQi−Rui)Qi+2λPuT=2(i∑PuQiQi−i∑RuiQi+λPuT) -
令 ð L u ð P u = 0 \frac{\eth L_u}{\eth P_u}=0 ðPuðLu=0,可以得到
∑ i P u Q i Q i − ∑ i R u i Q i + λ P u T = 0 \displaystyle\sum_{i}P_uQ_iQ_i-\displaystyle\sum_{i}R_{ui}Q_i+\lambda P_u^T =0 i∑PuQiQi−i∑RuiQi+λPuT=0P u Q i = ∑ i P u k Q k i = Q i T P u T P_uQ_i =\displaystyle\sum_{i}P_{uk}Q_{ki} =Q_i^TP_u^T PuQi=i∑PukQki=QiTPuT
-
由于 P u P_u Pu和 Q i Q_i Qi是向量
-
所以有
∑ i Q i T P u T Q i − ∑ i R u i Q i + λ P u T = 0 \displaystyle\sum_{i}Q_i^TP_u^TQ_i-\displaystyle\sum_{i}R_{ui}Q_i+\lambda P_u^T =0 i∑QiTPuTQi−i∑RuiQi+λPuT=0( ∑ i Q i Q I T + λ I ) P u T = ∑ i R u i Q i (\displaystyle\sum_{i}Q_iQ_I^T+\lambda I)P_u^T =\displaystyle\sum_{i}R_{ui}Q_i (i∑QiQIT+λI)PuT=i∑RuiQi
其中, I I I是单位矩阵
-
Q i Q_i Qi是物品i的特征向量,所以等式可以写为:
[ ( Q 1 , Q 2 , ⋯ , Q n ) ( Q 1 T , Q 2 T , ⋯ , Q n T ) T + λ I ] P u T = ( Q 1 , Q 2 , ⋯ , Q n ) ( R u 1 , R u 2 , ⋯ , R u n ) T [(Q_1,Q_2,\cdots,Q_n)(Q_1^T,Q_2^T,\cdots,Q_n^T)^T+\lambda I]P_u^T =(Q_1,Q_2,\cdots,Q_n)(R_{u1},R_{u2},\cdots,R_{un})^T [(Q1,Q2,⋯,Qn)(Q1T,Q2T,⋯,QnT)T+λI]PuT=(Q1,Q2,⋯,Qn)(Ru1,Ru2,⋯,Run)T -
可以看到,物品特征向量构成的矩阵,其实就是Q:
( Q 1 , Q 2 , ⋯ , Q n ) = Q (Q_1,Q_2,\cdots,Q_n)=Q (Q1,Q2,⋯,Qn)=Q -
所以可以得到:
( Q Q T + λ I ) P n T = Q R u (QQ^T+\lambda I)P_n^T =QR_u (QQT+λI)PnT=QRu -
解得:
P n T = ( Q Q T + λ I ) − 1 Q R u P_n^T =(QQ^T+\lambda I)^{-1}QR_u PnT=(QQT+λI)−1QRu -
这样一一解出每一个 P u P_u Pu,就可以得到这一步的用户特征矩阵P了
-
同样,下一次固定P时,可以解得:
Q i T = ( P P T + λ I ) − 1 P R i Q_i^T =(PP^T+\lambda I)^{-1}PR_i QiT=(PPT+λI)−1PRi
-
4.2.2.6、梯度下降算法LFM
经过ALS的洗礼,相信大家的水平已经有所提升,那么梯度下降算法直接就看图片吧。