吴恩达机器学习(十三)—— 推荐系统

推荐系统

1. 问题规划

  推荐系统是机器学习中的一个重要应用。
  在机器学习中,针对一些问题,有算法可以为系统自动学习一套好的特征。因此,不要试图手动设计,但手写代码是我们目前为止常干的事情。有一些设置,我们可以有一个算法,仅仅学习其使用的特征,推荐系统就是类型设置的一个例子。
  电影预测评分的例子如下。假使我们是一个电影供应商,现在有5部电影和4个用户,要求用户为电影打分。
吴恩达机器学习(十三)—— 推荐系统
  从上表所给信息可以看出,前三部电影是爱情片,后两部是动作片,Alice和Bob似乎更倾向与爱情片, 而Carol和Dave似乎更倾向与动作片,而且并没有一个用户给所有的电影都打过分。我们希望构建一个算法来预测他们每个人可能会给他们没看过的电影打多少分,并以此作为推荐的依据。

  下面引入一些标记:
   n u n_{u} nu​代表用户的数量;
   n m n_{m} nm​代表电影的数量;
   r ( i , j ) = 1 r(i, j)=1 r(i,j)=1代表用户 j j j给电影 i i i评过分;
   y ( i , j ) = 1 y(i, j)=1 y(i,j)=1代表用户 j j j对电影 i i i所给出的评分。

  在上述例子中, n u = 4 n_{u}=4 nu​=4, n m = 5 n_{m}=5 nm​=5,算法的预测结果如下所示。
吴恩达机器学习(十三)—— 推荐系统

2. 基于内容的推荐算法

  在一个基于内容的推荐系统算法中,我们假设对于我们希望推荐的东西有一些数据,这些数据是有关这些东西的特征。在电影预测评分的例子中,我们可以假设每部电影都有两个特征,如 x 1 x_{1} x1​代表电影的浪漫程度, x 2 x_{2} x2​代表电影的动作程度,则每部电影都有一个特征向量,如 x 1 x_{1} x1​是第一部电影的特征向量为[0.9 0],如下表所示。
吴恩达机器学习(十三)—— 推荐系统
  下面我们要基于这些特征来构建一个推荐系统算法。假设我们采用线性回归模型,我们可以针对 每一个用户都训练一个线性回归模型,如 θ ( 1 ) \theta^{(1)} θ(1) 是第一个用户的模型的参数。 假设 θ ( j ) \theta^{(j)} θ(j) 为用户 j j j 的参数向 量; x ( i ) x^{(i)} x(i) 为电影 i i i 的特征向量; 对于用户 j j j 和电影 i i i ,我们预测评分为 ( θ ( j ) ) T x ( i ) \left(\theta^{(j)}\right)^{T} x^{(i)} (θ(j))Tx(i) 。例如, x ( 3 ) = x^{(3)}= x(3)= [ 1 0.99 0 ] , θ ( 1 ) = [ 0 5 0 ] \left[\begin{array}{c}1 \\ 0.99 \\ 0\end{array}\right], \theta^{(1)}=\left[\begin{array}{l}0 \\ 5 \\ 0\end{array}\right] ⎣⎡​10.990​⎦⎤​,θ(1)=⎣⎡​050​⎦⎤​, 则第一个用户对第三部电影的评分预测为 ( θ ( 1 ) ) T x ( 3 ) = 0 × 1 + 5 × 0.99 + 0 × 0 = 4.95 \left(\theta^{(1)}\right)^{T} x^{(3)}=0 \times 1+5 \times 0.99+0 \times 0=4.95 (θ(1))Tx(3)=0×1+5×0.99+0×0=4.95 。

  针对用户 j j j, 该线性回归模型的代价为预测误差的平方和,加上正则化项:
min ⁡ θ ( j ) 1 2 ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ k = 1 n ( θ k ( j ) ) ) 2 \left.\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} \sum_{k=1}^{n}\left(\theta_{k}^{(j)}\right)\right)^{2} θ(j)min​21​i:r(i,j)=1∑​((θ(j))Tx(i)−y(i,j))2+2λ​k=1∑n​(θk(j)​)⎠⎞​2
  其中, ∑ i : r ( i , j ) = 1 \sum_{i: r(i, j)=1} ∑i:r(i,j)=1​ 表示我们只对那些用户 j j j 评分过的电影进行求和。在一般的线性回归模型中,误差 项和正则项应该都是乘以 1 2 m \frac{1}{2 m} 2m1​, 在这里我们将 m m m 去掉,并且我们不对 θ ( 0 ) \theta_{(0)} θ(0)​ 项进行正则化处理。 上面的代价函数只是针对一个用户,为了学习所有用户,我们将所有用户的代价函数求和:
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 \left.\min _{\theta^{(1)}, \theta^{(2)}, \ldots, \theta^{\left(n_{u}\right)}} \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)\right)^{2} θ(1),θ(2),…,θ(nu​)min​21​j=1∑nu​​i:r(i,j)=1∑​((θ(j))Tx(i)−y(i,j))2+2λ​j=1∑nu​​k=1∑n​(θk(j)​)⎠⎞​2

  如果我们要用梯度下降法来求解最优解,我们计算代价函数的偏导数后得到梯度下降的更新公式 为:
θ k ( j ) : = θ k ( j ) − α ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) (  for  k = 0 ) θ k ( j ) : = θ k ( j ) − α ( ∑ i : r ( i , j ) = 1 ) ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) + λ θ k ( j ) ) (  for  k ≠ 0 ) \begin{aligned} &\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(\text { for } k=0) \\ &\theta_{k}^{(j)}:=\theta_{k}^{(j)}-\alpha\left(\sum_{i: 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(\text { for } k \neq 0) \end{aligned} ​θk(j)​:=θk(j)​−αi:r(i,j)=1∑​((θ(j))Tx(i)−y(i,j))xk(i)​( for k=0)θk(j)​:=θk(j)​−α⎝⎛​i:r(i,j)=1)∑​((θ(j))Tx(i)−y(i,j))xk(i)​+λθk(j)​⎠⎞​( for k​=0)​

3. 协同过滤

  在之前的基于内容的推荐系统中,对于每一部电影, 我们都掌握了可用的特征,使用这些特征训 练出了每一个用户的参数。相反地,如果我们拥有用户的参数,我们可以学习得出电影的特征。但是 如果当我们既没有用户的参数,也没有电影的特征,这两种方法就都不可行了。协同过滤算法可以同 时学习这两者。 优化目标算法为:
给定 θ ( 1 ) , … , θ ( n u ) \theta^{(1)}, \ldots, \theta^{\left(n_{u}\right)} θ(1),…,θ(nu​), 去学习 x ( i ) x^{(i)} x(i) :
min ⁡ x ( i ) 1 2 ∑ j : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ k = 1 n ( x k ( i ) ) ) 2 \left.\min _{x^{(i)}} \frac{1}{2} \sum_{j: r(i, j)=1}\left(\left(\theta^{(j)}\right)^{T} x^{(i)}-y^{(i, j)}\right)^{2}+\frac{\lambda}{2} \sum_{k=1}^{n}\left(x_{k}^{(i)}\right)\right)^{2} x(i)min​21​j:r(i,j)=1∑​((θ(j))Tx(i)−y(i,j))2+2λ​k=1∑n​(xk(i)​)⎠⎞​2
  给定 θ ( 1 ) , … , θ ( n u ) \theta^{(1)}, \ldots, \theta^{\left(n_{u}\right)} θ(1),…,θ(nu​), 去学习 x ( 1 ) , … , x ( n m ) x^{(1)}, \ldots, x^{\left(n_{m}\right)} x(1),…,x(nm​) :
min ⁡ x ( 1 ) , … , x ( n m ) 1 2 ∑ i = 1 n m ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ i = 1 n m ∑ k = 1 n ( x k ( i ) ) ) 2 \left.\min _{x^{(1)}, \ldots, x^{\left(n_{m}\right)}} \frac{1}{2} \sum_{i=1}^{n_{m}} \sum_{i: 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)\right)^{2} x(1),…,x(nm​)min​21​i=1∑nm​​i:r(i,j)=1∑​((θ(j))Tx(i)−y(i,j))2+2λ​i=1∑nm​​k=1∑n​(xk(i)​)⎠⎞​2

  协同滤波算法为:
  给定 x ( 1 ) , . . . , x ( n m ) x^{(1)},...,x^{(n_{m})} x(1),...,x(nm​),估计 θ ( 1 ) , . . . , θ ( n u ) \theta^{(1)},...,\theta^{(n_{u})} θ(1),...,θ(nu​);
  给定 θ ( 1 ) , . . . , θ ( n u ) \theta^{(1)},...,\theta^{(n_{u})} θ(1),...,θ(nu​),估计 x ( 1 ) , . . . , x ( n m ) x^{(1)},...,x^{(n_{m})} x(1),...,x(nm​);
  通过迭代( θ → x → θ → x → θ → x . . . \theta \rightarrow x\rightarrow \theta\rightarrow x\rightarrow \theta \rightarrow x... θ→x→θ→x→θ→x...)得到更好的 θ \theta θ、 x x x,并且算法会收敛到一组好的用户参数及合理的特征。

  协同滤波算法指的是当我们执行算法时,要观察大量的用户,观察这些用户的实际行为来协调地得到对个用户对电影更佳的评分值。因为如果每个用户都对一部分电影做出了评价,那么每个用户都在帮助算法学习出更合适的特征,然后这些学习出的特征又可以被用来更好地预测其他用户的评分。协同的意思是每位用户都在帮助算法更好地进行特征学习,这就是协调滤波。

4. 协同过滤算法

  协同过滤的优化目标:

  给定 x ( 1 ) , … , x ( n m ) x^{(1)}, \ldots, x^{\left(n_{m}\right)} x(1),…,x(nm​), 估计 θ ( 1 ) , … , θ ( n u ) \theta^{(1)}, \ldots, \theta^{\left(n_{u}\right)} θ(1),…,θ(nu​) :
min ⁡ θ ( 1 ) , … , θ ( 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 \left.\min _{\left.\theta^{(1)}, \ldots, \theta^{\left(n_{u}\right.}\right)} \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)\right)^{2} θ(1),…,θ(nu​)min​21​j=1∑nu​​i:r(i,j)=1∑​((θ(j))Tx(i)−y(i,j))2+2λ​j=1∑nu​​k=1∑n​(θk(j)​)⎠⎞​2
  给定 θ ( 1 ) , … , θ ( n u ) \theta^{(1)}, \ldots, \theta^{\left(n_{u}\right)} θ(1),…,θ(nu​), 估计 x ( 1 ) , … , x ( n m ) : x^{(1)}, \ldots, x^{\left(n_{m}\right)}: x(1),…,x(nm​):
min ⁡ x ( 1 ) , … , x ( n m ) 1 2 ∑ i = 1 n m ∑ i : r ( i , j ) = 1 ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) 2 + λ 2 ∑ i = 1 n m ∑ k = 1 n ( x k ( i ) ) ) 2 \left.\min _{x^{(1)}, \ldots, x^{\left(n_{m}\right)}} \frac{1}{2} \sum_{i=1}^{n_{m}} \sum_{i: 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)\right)^{2} x(1),…,x(nm​)min​21​i=1∑nm​​i:r(i,j)=1∑​((θ(j))Tx(i)−y(i,j))2+2λ​i=1∑nm​​k=1∑n​(xk(i)​)⎠⎞​2
  同时最小化 x ( 1 ) , … , x ( n m ) , θ ( 1 ) , … , θ ( n u ) : x^{(1)}, \ldots, x^{\left(n_{m}\right)}, \theta^{(1)}, \ldots, \theta^{\left(n_{u}\right)}: x(1),…,x(nm​),θ(1),…,θ(nu​):
吴恩达机器学习(十三)—— 推荐系统

  如果我们要用梯度下降法来求解最优解,我们计算代价函数的偏导数后得到梯度下降的更新公式为:
x k ( i ) : = x k ( i ) − α ( ∑ j : r ( i , j ) = 1 ) ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) θ k ( j ) + λ x k ( i ) ) θ k ( j ) : = θ k ( j ) − α ( ∑ i : r ( i , j ) = 1 ) ( ( θ ( j ) ) T x ( i ) − y ( i , j ) ) x k ( i ) + λ θ k ( j ) ) \begin{aligned} &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)}\right) \theta_{k}^{(j)}+\lambda x_{k}^{(i)}\right) \\ &\theta_{k}^{(j)}:=\theta_{k}^{(j)}-\alpha\left(\sum_{i: r(i, j)=1)}\left(\left(\theta^{(j)}\right)^{T} x^{(i)}-y^{(i, j)}\right) x_{k}^{(i)}+\lambda \theta_{k}^{(j)}\right) \end{aligned} ​xk(i)​:=xk(i)​−α⎝⎛​j:r(i,j)=1)∑​((θ(j))Tx(i)−y(i,j))θk(j)​+λxk(i)​⎠⎞​θk(j)​:=θk(j)​−α⎝⎛​i:r(i,j)=1)∑​((θ(j))Tx(i)−y(i,j))xk(i)​+λθk(j)​⎠⎞​​
  协同过滤算法:

  1. 初始化 x ( 1 ) , … , x ( n m ) , θ ( 1 ) , … , θ ( n u ) x^{(1)}, \ldots, x^{\left(n_{m}\right)}, \theta^{(1)}, \ldots, \theta^{\left(n_{u}\right)} x(1),…,x(nm​),θ(1),…,θ(nu​) 为一些小的随机值;
  2. 使用梯度下降算法最小化代价函数 J J J;
  3. 对于拥有参数 θ \theta θ 的用户和特征 x x x 的电影, 预测评分为 θ T x   \theta^{T} x_{\text { }} θTx ​

5. 向量化:低秩矩阵分解

  接下来介绍有关协同滤波算法的向量化实现,以及该算法可以做的其他事情。例如,1. 当给出一件产品时,能否找到与之相关的其他产品;2. 一位用户最近看上一件产品,有没有其他相关的产品可以推荐给他。
  我们要做的是,实现另一种方法写出协同过滤算法的预测情况。我们有关于五部电影的数据集,将这些用户的电影评分,进行分组并存到一个矩阵中。
吴恩达机器学习(十三)—— 推荐系统
  我们有五部电影,以及四位用户,那么这个矩阵 Y Y Y就是一个5行4列的矩阵,它将这些电影的用户评分数据都存在矩阵里,如下所示。

Y = [ 5 5 0 0 5 ? ? 0 ? 4 0 ? 0 0 5 4 0 0 5 0 ] Y=\left[\begin{array}{llll} 5 & 5 & 0 & 0 \\ 5 & ? & ? & 0 \\ ? & 4 & 0 & ? \\ 0 & 0 & 5 & 4 \\ 0 & 0 & 5 & 0 \end{array}\right] Y=⎣⎢⎢⎢⎢⎡​55?00​5?400​0?055​00?40​⎦⎥⎥⎥⎥⎤​

  预测出评分为:
[ ( θ ( 1 ) ) T x ( 1 ) ( θ ( 2 ) ) T x ( 1 ) … ( θ ( n u ) ) T x ( 1 ) ( θ ( 1 ) ) T x ( 2 ) ( θ ( 2 ) ) T x ( 2 ) ⋯ ( θ ( n u ) ) T x ( 2 ) ⋮ ⋮ ⋱ ⋮ ( θ ( 1 ) ) T x ( n m ) ( θ ( 2 ) ) T x ( n m ) ⋯ ( θ ( n u ) ) T x ( n m ) ] = X Θ T  其中,  X = [ − ( x ( 1 ) ) T − − ( x ( 2 ) ) T − ⋮ − ( x ( n m ) ) T − ] , Θ = [ − ( θ ( 1 ) ) T − − ( θ ( 2 ) ) T − ⋮ − ( θ ( n u ) ) T − ]  .  \begin{gathered} {\left[\begin{array}{cccc} \left(\theta^{(1)}\right)^{T} x^{(1)} & \left(\theta^{(2)}\right)^{T} x^{(1)} & \ldots & \left(\theta^{\left(n_{u}\right)}\right)^{T} x^{(1)} \\ \left(\theta^{(1)}\right)^{T} x^{(2)} & \left(\theta^{(2)}\right)^{T} x^{(2)} & \cdots & \left(\theta^{\left(n_{u}\right)}\right)^{T} x^{(2)} \\ \vdots & \vdots & \ddots & \vdots \\ \left(\theta^{(1)}\right)^{T} x^{\left(n_{m}\right)} & \left(\theta^{(2)}\right)^{T} x^{\left(n_{m}\right)} & \cdots & \left(\theta^{\left(n_{u}\right)}\right)^{T} x^{\left(n_{m}\right)} \end{array}\right]=X \Theta^{T}} \\ \text { 其中, } X=\left[\begin{array}{c} -\left(x^{(1)}\right)^{T}- \\ -\left(x^{(2)}\right)^{T}- \\ \vdots \\ -\left(x^{\left(n_{m}\right)}\right)^{T}- \end{array}\right], \Theta=\left[\begin{array}{c} -\left(\theta^{(1)}\right)^{T}- \\ -\left(\theta^{(2)}\right)^{T}- \\ \vdots \\ -\left(\theta^{\left(n_{u}\right)}\right)^{T}- \end{array}\right] \text { . } \end{gathered} ⎣⎢⎢⎢⎢⎡​(θ(1))Tx(1)(θ(1))Tx(2)⋮(θ(1))Tx(nm​)​(θ(2))Tx(1)(θ(2))Tx(2)⋮(θ(2))Tx(nm​)​…⋯⋱⋯​(θ(nu​))Tx(1)(θ(nu​))Tx(2)⋮(θ(nu​))Tx(nm​)​⎦⎥⎥⎥⎥⎤​=XΘT 其中, X=⎣⎢⎢⎢⎢⎡​−(x(1))T−−(x(2))T−⋮−(x(nm​))T−​⎦⎥⎥⎥⎥⎤​,Θ=⎣⎢⎢⎢⎢⎡​−(θ(1))T−−(θ(2))T−⋮−(θ(nu​))T−​⎦⎥⎥⎥⎥⎤​ . ​
  找到相关推荐影片:当用户在看某部电影 i i i的时候,为了能给用户推荐5部新电影,我们需要做的是找出5部与电影 i i i非常相似的电影 j j j。电影 i i i有一个特征向量 x ( i ) x^{(i)} x(i),那么我们只要保证两部电影的特征向量 x ( i ) x^{(i)} x(i)和 x ( j ) x^{(j)} x(j)之间的距离 ∥ x ( i ) − x ( j ) ∥ \left \|x^{(i)}-x^{(j)} \right \| ∥∥​x(i)−x(j)∥∥​很小,那就能很有力地表明电影 i i i和电影 j j j在某种程度上有相似,这样你就能给你的用户推荐几部不同的电影了。

6. 均值归一化

  如果我们在上述预测电影评分例子的基础上新增一个用户Eve,并且Eve没有为任何电影评分,那么我们以什么为依据为Eve推荐电影呢?
吴恩达机器学习(十三)—— 推荐系统
  我们首先需要对结果矩阵 Y Y Y 进行均值归一化处理,将每一个用户对某一部电影的评分减去所有用户对该电影评分的平均值:
Y = [ 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 = [ 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=\left[\begin{array}{ccccc} 5 & 5 & 0 & 0 & ? \\ 5 & ? & ? & 0 & ? \\ ? & 4 & 0 & ? & ? \\ 0 & 0 & 5 & 4 & ? \\ 0 & 0 & 5 & 0 & ? \end{array}\right] \quad \mu=\left[\begin{array}{c} 2.5 \\ 2.5 \\ 2 \\ 2.25 \\ 1.25 \end{array}\right] \rightarrow Y=\left[\begin{array}{ccccc} 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=⎣⎢⎢⎢⎢⎡​55?00​5?400​0?055​00?40​?????​⎦⎥⎥⎥⎥⎤​μ=⎣⎢⎢⎢⎢⎡​2.52.522.251.25​⎦⎥⎥⎥⎥⎤​→Y=⎣⎢⎢⎢⎢⎡​2.52.5?−2.25−1.25​2.5?2−2.25−1.25​−2.5?−22.753.75​−2.5−2.5?1.75−1.25​?????​⎦⎥⎥⎥⎥⎤​
  然后我们利用这个新的 Y Y Y 矩阵来训练算法。如果我们要用新训练出的算法来预测评分, 则需要将平均值重新加回去, 预测用户 j j j 给电 影 i i i 的评分为 ( θ ( j ) ) T x ( i ) + μ i \left(\theta^{(j)}\right)^{T} x^{(i)}+\mu_{i} (θ(j))Tx(i)+μi​ 。对于Eve, 我们的新模型会认为她给每部电影的评分都是该电影的平均分。

上一篇:Spring_Mybatis_事务处理


下一篇:13-jpql查询-分页查询