1. 推荐系统介绍
对机器学习来说,特征是很重要的,往往所选的特征将会决定我们的模型建立的好坏。因此,在机器学习中有一种思想,它针对一些问题,有算法可以为你自动学习一套好的特征。推荐算法算是一个可以自动学习特征的算法,还有很多其它的,接下来从推荐算法来介绍怎么使用推荐算法进行特征自动学习,以及推荐系统的构建和应用;
举一个例子:
假使我们是一个电影供应商,我们有 5 部电影和 4 个用户,我们要求用户为电影打分。
前面三部电影是爱情片, 后两部是动作片,可以看出前两个用户更偏向于爱情片,后两个用户更倾向于动作片。并且可以看到并不是每一个用户给对所有的电影都打过分, 可能是没有看过该电影,也可能是看过电影后没有给电影打分。所以,推荐系统的目标来了,就是系统通过构建一个算法来预测他们每个人可能会给他们没打过分的电影打多少分,并以此来作为推荐的依据;
给数据集引入一些标记, 下面关于推荐算法的推倒便基于这些标记:
$n_u$代表用户的数量
$n_m$代表电影的数量
$r ( i , j )$如果用户 j 给电影 i 评分过则 r(i, j) = 1
$y^{(i, j)}$代表用户 j 给电影的评分
$m_j$代表用户 j 评过分的电影总数
基于内容的推荐系统
在基于内容的推荐算法中,被推荐的内容往往有一些特征,我们要做的就是根据这些内容的特征,通过特征内容和被推荐人的符合程度,来进行推荐;
下面举一个例子,假设每部电影都有两个特征,如 x1 代表电影的浪漫程度,x2 代表电影的动作程度
每部电影都有一个特征向量,如 $x^{(1)}$ 是第一部电影的特征向量为[0.9 0]。
接下来根据这些特征来构建一个推荐算法。比如使用线型回归模型,可以现针对每一个用户都训练一个线型回归模型,如$\theta^{(1)}$是第一个用户的模型的参数。于是,推荐算法可以归纳为:
预测函数
$\theta^{(j)}$是用户 j 的参数向量
$x^{(i)}$是电影 i 的特征向量
对于用户 j 和电影 i ,我们预测评分为: $\left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) }$
代价函数
针对用户 j ,该线性回归模型的代价为预测误差的平方和,加上正则化项:
$\min _ { \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 }$
其中 i : r( i, j ) 表示我们只计算那些用户 j 评过分的电影。在一般的线性回归模型中,误差项和正则项应该都是乘以 1/2m ,在这里我们将 m 去掉。并且我们不对方差项 θ0 进行正则化处理。
优化目标
上面的代价函数只是针对一个用户的,为了学习所有用户,将所有用户的代价函数求和:
$\min _ { \theta ^ { ( 1 ) } , \ldots , \theta ^ { ( n ) } } \frac { 1 } { 2 } \sum _ { j = 1 } ^ { n _ { n } } \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 _ { s } } \sum _ { k = 1 } ^ { n } \left( \theta _ { k } ^ { ( j ) } \right) ^ { 2 }$
$\theta _ { k } ^ { ( j ) } : = \theta _ { k } ^ { ( j ) } - \alpha \sum _ { i : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } \right) x _ { k } ^ { ( i ) } \quad ($ for $k = 0 )$
$\theta _ { k } ^ { ( j ) } : = \theta _ { k } ^ { ( j ) } - \alpha \left( \sum _ { i r r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } \right) x _ { k } ^ { ( i ) } + \lambda \theta _ { k } ^ { ( j ) } \right) \quad ($ for $k \neq 0 )$
协同过滤
通过参数来学习特征
上面的例子是我们通过每一个内容的特征,使用这些特种来训练每一个用户的参数;同样的我们也可以根据用户的参数,来学习电影的特征;这样我们就可以根据已有的用户,来给所有未进行特征提取的电影进行特征的建立;
优化目标
$\min _ { x ^ { ( 1 ) } , \ldots , x ^ { ( 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
协同过滤
如果在建立系统的最开始,既没有用户的参数,也没有电影的特征,那么既不能通过特征来学习参数,也不能通过参数来学习特征,这两种方法都不可行了。协同过滤算法可以同时学习这两者。
协同过滤算法
如果给定x(1), …., x(nm),那么估计θ(1), ….θ(nu):
如果给定θ(1), ….θ(nu), 那么估计x(1), …., x(nm)
代价函数
$J \left( x ^ { ( 1 ) } , \ldots x ^ { \left( n _ { m } \right) } , \theta ^ { ( 1 ) } , \ldots , \theta ^ { \left( n _ { s } \right) } \right) = \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 } ^ { ( j ) } \right) ^ { 2 } + \frac { \lambda } { 2 } \sum _ { j = 1 } ^ { n _ { u } } \sum _ { k = 1 } ^ { n } \left( \theta _ { k } ^ { ( j ) } \right) ^ { 2 }$
优化目标优化函数
$\min _ { x ^ { ( 1 ) } , \ldots , x ^ { \left( n _ { m } \right) } \theta ^ { ( 1 ) } , \ldots , \theta ^ { \left( n _ { u } \right) } } J \left( x ^ { ( 1 ) } , \ldots , x ^ { \left( n _ { m } \right) } , \theta ^ { ( 1 ) } , \ldots , \theta ^ { \left( n _ { u } \right) } \right)$
$x _ { k } ^ { ( i ) } : = x _ { k } ^ { ( i ) } - \alpha \left( \sum _ { j : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } \theta _ { k } ^ { j } + \lambda x _ { k } ^ { ( i ) } \right)\right.$
$\theta _ { k } ^ { ( i ) } : = \theta _ { k } ^ { ( i ) } - \alpha \left( \sum _ { i : r ( i , j ) = 1 } \left( \left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } - y ^ { ( i , j ) } x _ { k } ^ { ( i ) } + \lambda \theta _ { k } ^ { ( j ) } \right)\right.$
备注: 在协同过滤算法中,不需要特地的去学习方差项, 即线性回归的常数项,因为如果需要, 我们初始化θ后, 算法会自动的将一个特征学习为方差项
协同过滤步骤:
- 先初始化$x ^ { ( 1 ) } , x ^ { ( 1 ) } , \ldots x ^ { ( n m ) } , \theta ^ { ( 1 ) } , \theta ^ { ( 2 ) } , \ldots , \theta ^ { \left( n _ { 2 } \right) }$, 为一些随机小值
- 使用梯度下降算出最小化的代价函数
- 训练完成后, 预测用户给 j 电影 i 的评分
通过这个学习过程获得的特征矩阵包含了有关电影的重要数据,这些数据不总是人能读懂的,但是我们可以用这些数据作为给用户推荐电影的依据。
例如,如果一位用户正在观看电影 $x^{(i)}$ ,我们可以寻找另一部电影 $x^{(j)}$ ,依据两部电影的特征向量之间的距离 $\left| x ^ { ( i ) } - x ^ { ( j ) } \right|$ 大小
向量化: 低秩矩阵分解
先举一个协同算法的例子:
- 当给出一件产品时,你能否找到与之相关的其它产品。
- 一位用户最近看上一件产品,有没有其它相关的产品,你可以推荐给他。
为了实现这些功能, 可以实现一种选择的方法,写出协同过滤算法的预测情况
有关于五部电影的数据集,我将要做的是,将这些用户的电影评分,进行分组并存到一个矩阵中。
我们有五部电影,以及四位用户,那么 这个矩阵 就是一个5行4列的矩阵,它将这些电影的用户评分数据都存在矩阵里:
零均值化
如果我们新增一个用户 Eve,并且 Eve 没有为任何电影评分,那么我们以什么为依据为Eve推荐电影呢?
如果按照我们之前的协同过滤算法获得的模型,由于Eve没有对任何电影进行评分,所以为了优化模型,减少误差,最终Eve的所有特征参数都将为0,因为这样的损失是最小的,就会导致对其电影评分的预测都将是0, 那么就没有办法对其进行电影推荐;
怎么让没有评价记录的用户的预测不为0:
首先需要对结果 Y 矩阵进行零均值化,将每一个用户对某一部电影的评分减去所有用户对该电影评分的平均值:
然后我们利用这个新的 Y 矩阵来训练算法。 如果我们要用新训练出的算法来预测评分,则需要将平均值重新加回去,预测 $\left( \theta ^ { ( j ) } \right) ^ { T } x ^ { ( i ) } + \mu _ { i }$,对于Eve,我们的新模型会认为她给每部电影的评分都是该电影的平均分, 这样就防止了其对所有的电影评分都为了,导致推荐系统异常的判断。