在本节中,我们将基于内容的推荐算法,与基于协同过滤的推荐算法,集合在一起,形成深度学习推荐算法,同时为了提高运行效率,我们还将介绍算法的向量表示。
在这里我们希望同时学习学生对题目需要程度的参数集
{θ(1),θ(2),...,θ(nu)}
和每道题目的特征向量
{x(1),x(2),...,x(nm)}
,我们可以将上两节的代价函数进行合并,上两节的代价函数如下所示:
J(θ(1),θ(2),...,θ(nu))=12∑j=1nu∑i:r(i,j)=1(θ(j)2x(i)−y(i,j))2+λ2∑j=1nu∑k=1nθ(j)k2
J(x(1),x(2),...,x(nm))=12∑i=1nm∑i:r(i,j)=1(θ(j)2x(i)−y(i,j))2+λ2∑i=1nm∑k=1nx(i)k2
我们先来分析第一项也就是平方和叠加项,第一个公式的意思是对每个用户,求出该用户所有打过分的影片,求出计算出的打分与用户实际打分之间误差的平方和,第二个公式的意思是对每部影片,求出所有对这部影片打过分的用户,求出计算出的打分与用户实际打分之间误差的平方和。实际上,这两个求误差平方和项计算出来的结果都是所有打过分的影片,计算的打分值与实际打分值之差的平方和,即这两项都等价于:
∑i:r(i,j)=1(θ(j)2x(i)−y(i,j))2
所以我们得到新的代价函数公式为:
J(x(1),x(2),...,x(nm),θ(1),θ(2),...,θ(nu))=∑i:r(i,j)=1(θ(j)2x(i)−y(i,j))2+λ2∑i=1nm∑k=1nx(i)k2+λ2∑j=1nu∑k=1nθ(j)k2
我们学习算法要优化的目标就变为:
minx(1),x(2),...,x(nm)θ(1),θ(2),...,θ(nu)J(x(1),x(2),...,x(nm),θ(1),θ(2),...,θ(nu))
与之前算法不同的是,我们这里不再需要传统线性回归
y=wx+b
因为根据上一节内容,
θ(0)=0
,所以我们不再需要向
x
和
θ
上添加第0维了,因此
x∈Rn,θ∈Rn
,在我们这个问题中
n=2
,表示题目是知识点1还是知识点2。
我们首先利用随机数初始化
{θ(1),θ(2),...,θ(nu)}
和每道题目的特征向量
{x(1),x(2),...,x(nm)}
为小的随机数。
对于
i=1,…,nm;k=1,…,n
:
x(i)k=x(i)k−α(∑i:r(i,j)=1(θ(j)Tx(i)−y(i,j))θ(j)k+λx(i)k)
对于
j=1,…,nu;k=1,…,n
:
θ(j)k=θ(j)k−α(∑i:r(i,j)=1(θ(j)Tx(i)−y(i,j))x(i)k+λθ(j)k)
当训练完成之后,如果学生j没有见过题目i,我们希望预测学生j对题目i的需要程度,进而决定是否向学生j推荐题目i,方法如下所示:
θ(j)Tx(i)
得到这个值之后,我们就可以决定是否向学生j推荐题目i了。
在前面章节中,我们讨论算法时都是用下标形式来讨论的,这样做的好处是比较直观,我们很容易理解算法。但是在实际应用中,如果直接应用前面章节中的公式,那么计算效率将是比较低的。因此,我们通常将算法转化为矩阵运算形式。
我们来看我们所研究的数据集:
* |
题目 |
张一 |
李二 |
王三 |
赵四 |
x(1)
|
题目1 |
5 |
5 |
0 |
0 |
x(2)
|
题目2 |
5 |
? |
? |
0 |
x(3)
|
题目3 |
? |
4 |
0 |
? |
x(4)
|
题目4 |
0 |
0 |
5 |
4 |
x(5)
|
题目5 |
0 |
0 |
5 |
? |
我们可以将上述评分结果,组成一个结果矩阵Y,如下所示:
Y=⎡⎣⎢⎢⎢⎢⎢⎢5.05.0?0.00.05.0?4.00.00.00.0?0.05.05.00.00.0?4.0?⎤⎦⎥⎥⎥⎥⎥⎥
由上面定义可以看出,
Y∈Rnm×nu
,即行对应于某道题目,列对应于某个用户。我们以前的
y(i,j)=Yi,j=θ(j)Tx(i)
。
则结果矩阵可以表示为:
Y=⎡⎣⎢⎢⎢⎢⎢⎢5.05.0?0.00.05.0?4.00.00.00.0?0.05.05.00.00.0?4.0?⎤⎦⎥⎥⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢θ(1)Tx(1)θ(1)Tx(2)θ(1)Tx(3)θ(1)Tx(4)θ(1)Tx(5)θ(2)Tx(1)θ(2)Tx(2)θ(2)Tx(3)θ(2)Tx(4)θ(2)Tx(5)θ(3)Tx(1)θ(3)Tx(2)θ(3)Tx(3)θ(3)Tx(4)θ(3)Tx(5)θ(4)Tx(1)θ(4)Tx(2)θ(4)Tx(3)θ(4)Tx(4)θ(4)Tx(5)⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥
我们令设计矩阵X为:
X=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢x(1)Tx(2)Tx(3)Tx(4)Tx(5)T⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥
其中
X∈Rnm×n
的矩阵。
上式中两侧的横线代有将列向量转置为行向量,同样我们令参数矩阵
Θ
为:
Θ=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢θ(1)Tθ(2)Tθ(3)Tθ(4)Tθ(5)T⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥
其中
Θ∈Rnu×n
。
有了上面两个定义,我们就可以将结果矩阵表示为:
Y=X⋅ΘT=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢x(1)Tx(2)Tx(3)Tx(4)Tx(5)T⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⋅[θ(1)θ(2)θ(3)θ(4)]
上面讨论的是前向传播问题,而在计算梯度和利用随机梯度下降算法来进行学习时,还需要用我们之前介绍的公式来计算。
有了这些理论知识之后,我们就可以来解决一类非常常见的推荐问题了,例如学生j观做过题目i,我们就可以向学生j推荐5个他可能需要的题目了。
我们首先取出题目
i
的特征向量
x(i)
,然后对所有其他题目算出欧式距离
d(l)
:
d(l)=∥x(i)−x(l)∥22,l=1,2,...,nm且l≠i
对于所有
d(l)
按从小到大进行排序,选出其中距离值最小的5个,就可以作为结果推荐给用户
j
了。
这里面实际上还有一个问题,如果我们有成千上万部影片,我们算出某部影片的与其他所有影片的欧式距离,并从小到大排序,最后选出5个最小的推荐给用户,这将花费很长时间,用户肯定不愿意等待那么长时间。怎么解决这一问题呢?我们可以通过一个定时启动的后台线程,算出所有影片之间的欧式距离,并按从小到大排序,然后缓存在NoSQL数据库中,这样需要向用户推荐时,直接返回缓存中结果就可以了。如果我们定时启动的后台线程运行频率足够的话,我们就可以得到相对实时的效果了。
在这一节中,我们讲述了基于深度学习的推荐系统。但是在这里我们有一个实际问题,我们一直没有讨论,就是推荐系统的冷启动问题,如何从对学生一无所知开始进行推荐,这是一个非常实际的问题,在下一节中,我们将讨论怎样解决这个问题。