1 什么是推荐系统
推荐系统可以依靠你过去浏览的信息或者评价的电影来推荐新的信息。因此这会给互联网内容企业带来很大一部分收入,对企业有实质性的影响。
另外,对于机器学习算法来说,数据特征有很大的影响,不同的特征会影响算法的准确性和性能。对于特征的获取,我们可以手动设计数据特征,也可以设计一个算法来学习使用的特征。推荐系统就是后者的一个例子。
假如我们有五部电影和四个用户,每个用户对电影均有0-5的评分,如下图:
这里定义几个变量:
- n u n_u nu:用户的数量,=4
- n m n_m nm:电影的数量,=5
- r ( i , j ) r(i,j) r(i,j):用户j是否给电影i评分,若已评分,则 r ( i , j ) = 1 r(i,j)=1 r(i,j)=1
- y ( i , j ) y^{(i,j)} y(i,j):用户j给电影i的评分
- m j m_j mj:用户j评过分的电影的总数
2 基于内容的推荐系统
在基于内容的推荐系统中,系统所推荐的东西有一些代表特征。在上面所举的例子中,每部电影都有两个特征: x 1 x_1 x1代表电影的浪漫程度和 x 2 x_2 x2代表电影的动作程度。
基于电影的特征
[
x
1
,
x
2
]
[x_1,x_2]
[x1,x2]来构建推荐系统的算法,针对每一个用户都训练一个线性回归模型。其中,定义
θ
(
j
)
\theta^{(j)}
θ(j)为用户j的参数向量,
x
(
i
)
x^{(i)}
x(i)为电影i的特征向量,则预测评分为
(
θ
(
j
)
)
T
x
(
i
)
(\theta^{(j)})^Tx^{(i)}
(θ(j))Tx(i)。其中
x
(
i
)
x^{(i)}
x(i)的长度为3,其中偏置项为1不变。假设想预测用户1对电影3的评价,已知电影3的特征
x
(
3
)
x^{(3)}
x(3),假如我们得到用户1的参数向量,就可以得到该用户对电影的评价:
x
(
3
)
=
[
1
0.99
0
]
θ
(
1
)
=
[
0
5
0
]
(
θ
(
j
)
)
T
x
(
i
)
=
5
×
0.99
=
4.95
x^{(3)} = {\left[ \begin{array}{ccc}1 \\ 0.99\\0\end{array}\right ]} \qquad \theta^{(1)} = {\left[ \begin{array}{ccc}0 \\ 5\\0\end{array}\right ]} \qquad (\theta^{(j)})^Tx^{(i)} = 5\times0.99=4.95
x(3)=⎣⎡10.990⎦⎤θ(1)=⎣⎡050⎦⎤(θ(j))Tx(i)=5×0.99=4.95
那么如何求得用户的参数向量?
y
(
i
,
j
)
y^{(i,j)}
y(i,j)是用户j给电影i的真实评分,因此便可以使用线性回归来获得最优的用户参数,将预测误差的平方和作为代价函数为:
J
(
θ
(
j
)
)
=
1
2
∑
i
:
r
(
i
,
j
)
=
1
(
(
θ
(
j
)
)
T
x
i
−
y
(
i
,
j
)
)
2
+
λ
2
(
θ
k
(
j
)
)
2
min
θ
(
j
)
J
(
θ
(
j
)
)
J(\theta^{(j)}) = \frac { 1 } { 2 } \sum _ { i : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { i } - y ^ { ( i , j ) } \right) ^ { 2 } + \frac { \lambda } { 2 } \left( \theta _ { k } ^ { ( j ) } \right) ^ { 2 } \qquad \min_{\theta^{(j)}}J(\theta^{(j)})
J(θ(j))=21i:r(i,j)=1∑((θ(j))Txi−y(i,j))2+2λ(θk(j))2θ(j)minJ(θ(j))
其中
i
:
r
(
i
,
j
)
=
1
i:r (i, j)=1
i:r(i,j)=1表示我们仅计算用户评价过的电影的分数,我们要做的就是尽量减少代价函数
J
(
θ
(
j
)
)
J(\theta^{(j)})
J(θ(j))的值。上式只是针对用户j的线性回归,整个系统包含了
n
u
n_u
nu个用户,便得到以下式子:
min
θ
(
1
)
,
θ
(
2
)
,
…
,
θ
(
n
u
)
1
2
∑
j
=
1
n
u
∑
i
:
r
(
i
,
j
)
=
1
(
(
θ
(
j
)
)
T
x
(
i
)
−
y
(
i
,
j
)
)
2
+
λ
2
∑
j
=
1
n
u
∑
k
=
1
n
(
θ
k
(
j
)
)
2
\min_{\theta^{(1)},\theta^{(2)},…,\theta^{(n_u)}} \frac { 1 } { 2 } \sum _ { j = 1 } ^ { n _ { u } } \sum _ { i : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } \right) ^ { 2 } + \frac { \lambda } { 2 } \sum _ { j = 1 } ^ { n _ { u } } \sum _ { k = 1 } ^ { n } \left( \theta _ { k } ^ { ( j ) } \right) ^ { 2 }
θ(1),θ(2),…,θ(nu)min21j=1∑nui:r(i,j)=1∑((θ(j))Tx(i)−y(i,j))2+2λj=1∑nuk=1∑n(θk(j))2
使用梯度下降来获得最优解,其更新公式为:
θ
k
(
j
)
=
θ
k
(
j
)
−
α
∑
i
:
r
(
i
,
j
)
=
1
(
(
θ
(
j
)
)
T
x
(
i
)
−
y
(
i
,
j
)
)
x
k
(
i
)
(
k
=
0
)
\theta_k^{(j)} = \theta_k^{(j)} - \alpha \sum_{i:r(i,j)=1}((\theta^{(j)})^Tx^{(i)}-y^{(i,j)})x_k^{(i)}\quad (k=0)
θk(j)=θk(j)−αi:r(i,j)=1∑((θ(j))Tx(i)−y(i,j))xk(i)(k=0)
θ
k
(
j
)
=
θ
k
(
j
)
−
α
(
∑
i
:
r
(
i
,
j
)
=
1
(
(
θ
(
j
)
)
T
x
(
i
)
−
y
(
i
,
j
)
)
x
k
(
i
)
+
λ
θ
k
(
j
)
)
(
k
≠
0
)
\theta_k^{(j)} = \theta_k^{(j)} - \alpha (\sum_{i:r(i,j)=1}((\theta^{(j)})^Tx^{(i)}-y^{(i,j)})x_k^{(i)}+\lambda\theta_k^{(j)})\quad (k\ne0)
θk(j)=θk(j)−α(i:r(i,j)=1∑((θ(j))Tx(i)−y(i,j))xk(i)+λθk(j))(k̸=0)
3 协同过滤
在基于内容的推荐系统中,我们已知电影特征来求得用户的参数特征,同样的如果我们知道用户的参数特征,也可以通过上面的方法来求得电影特征:
min
x
(
1
)
,
x
(
2
)
,
…
,
x
(
n
m
)
1
2
∑
i
=
1
n
m
∑
j
:
r
(
i
,
j
)
=
1
(
(
θ
(
j
)
)
T
x
(
i
)
−
y
(
i
,
j
)
)
2
+
λ
2
∑
i
=
1
n
m
∑
k
=
1
n
(
x
k
(
i
)
)
2
\min_{x^{(1)},x^{(2)},…,x^{(n_m)}} \frac { 1 } { 2 } \sum _ { i = 1 } ^ { n _ { m } } \sum _ { j : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } \right) ^ { 2 } + \frac { \lambda } { 2 } \sum _ { i = 1 } ^ { n _ { m } } \sum _ { k = 1 } ^ { n } \left( x_ { k } ^ { (i) } \right) ^ { 2 }
x(1),x(2),…,x(nm)min21i=1∑nmj:r(i,j)=1∑((θ(j))Tx(i)−y(i,j))2+2λi=1∑nmk=1∑n(xk(i))2
那么,根据电影特征和用户参数,这两者可以互相进行求出。协同过滤的基本思想就是是根据已知的某一参数A,来求得另一参数B,然后根据B再求A。通过这样的迭代过程,会逐渐得到更好的
θ
\theta
θ和
x
x
x,即算法自行学习到了一组合理的电影特征和用户参数。
但是上述的方法需要不停的重复计算
θ
\theta
θ和
x
x
x,我们可以重新定义一个可以同时优化
θ
\theta
θ和
x
x
x的代价函数J来提高算法效率:
J
(
x
(
1
)
,
…
,
x
(
n
m
)
,
θ
(
1
)
,
…
,
θ
(
n
u
)
)
=
1
2
∑
(
i
,
j
)
:
r
(
i
,
j
)
=
1
(
(
θ
(
j
)
)
T
x
(
i
)
−
y
(
i
,
j
)
)
2
+
λ
2
∑
i
=
1
n
m
∑
k
=
1
n
(
x
k
(
i
)
)
2
+
λ
2
∑
j
=
1
n
u
∑
k
=
1
n
(
θ
k
(
j
)
)
2
J(x^{(1)},…,x^{(n_m)},\theta^{(1)},…,\theta^{(n_u)})= \frac { 1 } { 2 } \sum _ {(i,j) : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } \right) ^ { 2 } + \frac { \lambda } { 2 } \sum _ { i = 1 } ^ { n _ { m } } \sum _ { k = 1 } ^ { n } \left( x_ { k } ^ { (i) } \right) ^ { 2 } + \frac { \lambda } { 2 } \sum _ { j = 1 } ^ { n _ { u } } \sum _ { k = 1 } ^ { n } \left( \theta_ { k } ^ { (j) } \right) ^ { 2 }
J(x(1),…,x(nm),θ(1),…,θ(nu))=21(i,j):r(i,j)=1∑((θ(j))Tx(i)−y(i,j))2+2λi=1∑nmk=1∑n(xk(i))2+2λj=1∑nuk=1∑n(θk(j))2
min
x
(
1
)
,
…
,
x
(
n
m
)
,
θ
(
1
)
,
…
,
θ
(
n
u
)
J
(
x
(
1
)
,
…
,
x
(
n
m
)
,
θ
(
1
)
,
…
,
θ
(
n
u
)
)
\min_{x^{(1)},…,x^{(n_m)},\theta^{(1)},…,\theta^{(n_u)}} J(x^{(1)},…,x^{(n_m)},\theta^{(1)},…,\theta^{(n_u)})
x(1),…,x(nm),θ(1),…,θ(nu)minJ(x(1),…,x(nm),θ(1),…,θ(nu))
当我们既不知道用户参数也不知道电影特征时,我们就需要上面的新的代价函数来计算
θ
\theta
θ和
x
x
x的最优解,这一过程就是协同过滤算法,它的基本步骤如下:
- 首先将 θ \theta θ和 x x x初始化为一些随机小值
- 使用梯度下降最小化J,得到
θ
\theta
θ和
x
x
x的最优解
θ k ( j ) = θ k ( j ) − α ( ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) + λ θ k ( j ) ) \theta_k^{(j)} = \theta_k^{(j)} - \alpha \left( \sum_{i:r(i,j)=1} \left(\left(\theta^{(j)}\right)^Tx^{(i)}-y^{(i,j)}\right)x_k^{(i)}+\lambda\theta_k^{(j)}\right) θk(j)=θk(j)−α⎝⎛i:r(i,j)=1∑((θ(j))Tx(i)−y(i,j))xk(i)+λθk(j)⎠⎞ x k ( i ) = x k ( i ) − α ( ∑ j : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) θ k ( j ) + λ x k ( i ) ) x_k^{(i)} = x_k^{(i)} - \alpha\left( \sum_{j:r(i,j)=1} \left (\left(\theta^{(j)}\right)^Tx^{(i)}-y^{(i,j)}\right)\theta_k^{(j)}+\lambda x_k^{(i)}\right) xk(i)=xk(i)−α⎝⎛j:r(i,j)=1∑((θ(j))Tx(i)−y(i,j))θk(j)+λxk(i)⎠⎞ - 训练完成后,预测 ( θ ( j ) ) T x ( i ) (\theta^{(j)})^Tx^{(i)} (θ(j))Tx(i)为用户j给电影i的评分
4 矢量化:低秩矩阵分解
本节讲的是协同过滤算法的向量化实现,我们将2图中的电影评分写入一个矩阵Y中如下;
Y
(
n
m
,
n
u
)
=
[
5
5
0
0
5
?
?
0
?
4
0
?
0
0
5
4
0
0
5
0
]
Y_{(n_m,n_u)}= { \left[ \begin{array}{ccc} 5 & 5 & 0 & 0\\ 5 & ? & ? & 0\\ ? & 4 & 0 & ?\\ 0 & 0 & 5 & 4\\ 0 & 0 & 5 & 0 \end{array} \right ]}
Y(nm,nu)=⎣⎢⎢⎢⎢⎡55?005?4000?05500?40⎦⎥⎥⎥⎥⎤
其中矩阵中的Y(i,j)就是用户j给电影i的评分,由公式
(
θ
(
j
)
)
T
x
(
i
)
(\theta^{(j)})^Tx^{(i)}
(θ(j))Tx(i),我们定义
X
(
n
m
,
n
)
X_{(n_m,n)}
X(nm,n)和
Θ
(
n
u
,
n
)
\Theta_{(n_u,n)}
Θ(nu,n)如下:
X
(
n
m
,
n
)
=
[
−
(
x
(
1
)
)
T
−
−
(
x
(
2
)
)
T
−
⋮
−
(
x
(
n
m
)
)
T
−
]
Θ
(
n
u
,
n
)
=
[
−
(
θ
(
1
)
)
T
−
−
(
θ
(
2
)
)
T
−
⋮
−
(
θ
(
n
u
)
)
T
−
]
X_{(n_m,n)}= { \left[ \begin{array}{ccc} -(x^{(1)})^T- \\ -(x^{(2)})^T- \\ \vdots\\ -(x^{(n_m)})^T- \end{array} \right ]} \quad \Theta_{(n_u,n)}={\left[ \begin{array}{ccc} -(\theta^{(1)})^T- \\ -(\theta^{(2)})^T- \\ \vdots\\ -(\theta^{(n_u)})^T- \end{array} \right ]}
X(nm,n)=⎣⎢⎢⎢⎡−(x(1))T−−(x(2))T−⋮−(x(nm))T−⎦⎥⎥⎥⎤Θ(nu,n)=⎣⎢⎢⎢⎡−(θ(1))T−−(θ(2))T−⋮−(θ(nu))T−⎦⎥⎥⎥⎤
那么很明显就可以得到预测结果
Y
(
n
m
,
n
u
)
=
X
(
n
m
,
n
)
×
Θ
(
n
u
,
n
)
T
Y_{(n_m,n_u)}=X_{(n_m,n)} \times\Theta_{(n_u,n)}^T
Y(nm,nu)=X(nm,n)×Θ(nu,n)T,这一过程也叫做低秩矩阵分解,向量化后,协同过滤算法变为:
J
(
X
(
n
m
,
n
)
,
Θ
(
n
u
,
n
)
)
=
1
2
∑
r
(
i
,
j
)
=
1
(
X
Θ
T
−
Y
)
2
+
λ
2
∑
X
2
+
λ
2
∑
Θ
2
J(X_{(n_m,n)},\Theta_{(n_u,n)})= \frac{1}{2} \sum_{r(i,j)=1}(X\Theta^T-Y)^2+\frac{\lambda}{2}\sum X^2+\frac{\lambda}{2}\sum \Theta^2
J(X(nm,n),Θ(nu,n))=21r(i,j)=1∑(XΘT−Y)2+2λ∑X2+2λ∑Θ2
Θ
=
Θ
−
α
(
(
X
Θ
T
−
Y
)
T
X
+
λ
Θ
)
\Theta = \Theta - \alpha\left( (X\Theta^T-Y)^TX+\lambda\Theta\right)
Θ=Θ−α((XΘT−Y)TX+λΘ)
X
=
X
−
α
(
(
X
Θ
T
−
Y
)
Θ
+
λ
X
)
X = X - \alpha\left( (X\Theta^T-Y)\Theta+\lambda X\right)
X=X−α((XΘT−Y)Θ+λX)
下面还有一个问题,如何利用已经知道的特征的电影找到与之相关的电影,即如何度量两部电影之间的相似性。比如电影i有一个特征向量
x
(
i
)
x^{(i)}
x(i),另一部电影j有
x
(
j
)
x^{(j)}
x(j),如果两者之间的距离很小,即
∣
∣
x
(
i
)
−
x
(
j
)
∣
∣
||x^{(i)}- x^{(j)}||
∣∣x(i)−x(j)∣∣很小,那么表明这两部电影就很类似。
5 均值规范化
假如我们在数据之中加一个用户,并且该用户没有对任何电影进行评分,则
如果我们采用协同过滤算法的话,则会将下式作为代价函数来求得最优解。但由于用户并未对电影进行评分,所以第一项不影响J的大小,而后两项正则化的最小值为0,也就是最优解为
x
(
i
)
=
0
,
θ
(
j
)
=
0
x^{(i)}=0,\theta^{(j)}=0
x(i)=0,θ(j)=0。所以使用协同过滤算法的预测结果为0,这时我们需要使用归一化法来解决这个问题。
J
(
x
(
1
)
,
…
,
x
(
n
m
)
,
θ
(
1
)
,
…
,
θ
(
n
u
)
)
=
1
2
∑
(
i
,
j
)
:
r
(
i
,
j
)
=
1
(
(
θ
(
j
)
)
T
x
(
i
)
−
y
(
i
,
j
)
)
2
+
λ
2
∑
i
=
1
n
m
∑
k
=
1
n
(
x
k
(
i
)
)
2
+
λ
2
∑
j
=
1
n
u
∑
k
=
1
n
(
θ
k
(
j
)
)
2
J(x^{(1)},…,x^{(n_m)},\theta^{(1)},…,\theta^{(n_u)})= \frac { 1 } { 2 } \sum _ {(i,j) : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } \right) ^ { 2 } + \frac { \lambda } { 2 } \sum _ { i = 1 } ^ { n _ { m } } \sum _ { k = 1 } ^ { n } \left( x_ { k } ^ { (i) } \right) ^ { 2 } + \frac { \lambda } { 2 } \sum _ { j = 1 } ^ { n _ { u } } \sum _ { k = 1 } ^ { n } \left( \theta_ { k } ^ { (j) } \right) ^ { 2 }
J(x(1),…,x(nm),θ(1),…,θ(nu))=21(i,j):r(i,j)=1∑((θ(j))Tx(i)−y(i,j))2+2λi=1∑nmk=1∑n(xk(i))2+2λj=1∑nuk=1∑n(θk(j))2
首先我们计算每个电影所得的分数的平均值,然后用矩阵Y减去
μ
\mu
μ得到一个新的矩阵
Y
(
n
m
,
n
u
)
=
[
5
5
0
0
?
5
?
?
0
?
?
4
0
?
?
0
0
5
4
?
0
0
5
0
?
]
μ
=
[
2.5
2.5
2
2.25
1.25
]
Y
(
n
m
,
n
u
)
—
μ
=
[
2.5
2.5
−
2.5
−
2.5
?
2.5
?
?
−
2.5
?
?
2
−
2
?
?
−
2.25
−
2.25
2.75
1.75
?
−
1.25
−
1.25
3.75
−
1.25
?
]
Y_{(n_m,n_u)}= { \left[ \begin{array}{ccc} 5 & 5 & 0 & 0& ?\\ 5 & ? & ? & 0& ?\\ ? & 4 & 0 & ?& ?\\ 0 & 0 & 5 & 4& ?\\ 0 & 0 & 5 & 0& ? \end{array} \right ]} \quad \mu = { \left[\begin{array}{ccc} 2.5\\2.5\\2\\2.25\\1.25 \end{array}\right]}\quad Y_{(n_m,n_u)}—\mu ={\left[ \begin{array}{ccc} 2.5 & 2.5 & -2.5 & -2.5& ?\\ 2.5 & ? & ? & -2.5& ?\\ ? & 2 &-2 & ?& ?\\ -2.25 & -2.25 & 2.75 &1.75& ?\\ -1.25 & -1.25 & 3.75 & -1.25& ? \end{array} \right ]}
Y(nm,nu)=⎣⎢⎢⎢⎢⎡55?005?4000?05500?40?????⎦⎥⎥⎥⎥⎤μ=⎣⎢⎢⎢⎢⎡2.52.522.251.25⎦⎥⎥⎥⎥⎤Y(nm,nu)—μ=⎣⎢⎢⎢⎢⎡2.52.5?−2.25−1.252.5?2−2.25−1.25−2.5?−22.753.75−2.5−2.5?1.75−1.25?????⎦⎥⎥⎥⎥⎤
现在使用协同过滤算法对新的矩阵进行求最优解
x
(
i
)
x^{(i)}
x(i)和
θ
(
j
)
\theta^{(j)}
θ(j),并进行预测。我们使用
x
(
i
)
(
θ
(
j
)
)
T
+
μ
i
x^{(i)}(\theta^{(j)})^T +\mu_i
x(i)(θ(j))T+μi来计算对与用户j对电影i的评价。这样对于新的用户来说,它的预测结果就是
μ
\mu
μ,即新用户给每部电影的评分都是平均分。