CollaborativeFiltering(协同过滤)
CollaborativeFiltering通常被使用在推荐系统(recommender system)中,在Spark中使用协同过滤是通过ALS(alternating least squares/交替最小二乘)这样一个Estimator对象。输入带有一组用户(user)对于一组产品(item)的评分(rating)矩阵数据作为训练集,通过交替最小二乘算法fit出最合适的矩阵分解数值(即ALSModel对象),再通过分解后的用户向量和产品向量transform出用户产品矩阵中的缺失值作为某个用户针对某个产品的预测评分(prediction)。
伪算法过程
迭代算法
根据训练集中评分数据的含义不同,协同过滤的计算方式分成2种——显式的(Explicit)和隐式的(Implicit)。
1.当训练数据集表示的评分矩阵中的评分值来自实际的用户打分时,比如用户对电影的评分,可以采用显式计算的方式。这时算法直接拟合用户对产品的评分数据,损失函数(Loss function)如下:
$$\sum_{i,j}(r_{ij}-u_i^Tv_j)^2$$ 其中$r_{ij}$是评分矩阵中第i个用户u对第j个产品v的评分值,$u_i$表示第i个用户的因子向量,$v_j$表示第j个产品的因子向量。拟合过程就是评分矩阵分解为用户因子矩阵和产品因子矩阵的乘积过程,先随机产生2个因子矩阵,然后通过迭代逼近损失函数最小值。
2.当训练数据集表示的评分矩阵中的评分值无法直接表示用户对产品的打分时,比如训练数据只有用户对产品的购买记录,评分值相当于购买次数,又或者评分值表达用户收看某个节目的时长等情况,这时可以采用隐式计算方式,Spark采用《Collaborative Filtering for Implicit Feedback Datasets》这篇文章的方式,这时的损失函数(Loss function)如下:
$$\sum_{i,j}c_{ij}(p_{ij}-u_{i}^{T}v_{j})^{2}$$ 其中$p_{ij}=1\{r_{ij}>0\}$,表示用户对产品的偏好程度(preference),当$r_{ij}>0$时为1,当$r_{ij}=0$时为0;
其中$c_{ij}=1+{\alpha}r_{ij}$,表示用户对商品的信任程度(confidence),具有最小值1,$r_{ij}$越大表示用户对该产品越信任,对该产品的偏好加持就更大,系数α是对信任程度加持权重的可调整参数。
正则化
正则化(Regularization)是用来防止模型过拟合(overfitting)的。Spark采用《Large-Scale Parallel Collaborative Filtering for the Netflix Prize》这篇论文中使用的吉洪诺夫正则(Tikhonov regularization),实际惩罚函数如下:
$$\sum_{i}n_{u_i}||u_i||^2+\sum_{j}n_{v_j}||v_j||^2$$其中$n_{u_i}$为第i个用户的评分总计次数,$n_{v_j}$为第j个产品的被评分总次数,$||u_i||^2$表示第i个用户的因子向量1范数的平方,$||v_j||^2$表示第j个产品的因子向量1范数的平方。
和逻辑回归算法类似,Spark提供了regParam参数来调整正则化的权重,越大表示对模型训练集进行迭代后,因子向量的系数越接近或者等于0。
参数
输入输出相关:
- userCol: 输入训练集中标记用户id的字段名称,该字段值必须是整数类型 (默认值: user)
- itemCol: 输入训练集中标记产品id的字段名称,该字段值必须是整数类型 (整数类型,默认值: item)
- ratingCol: 输入训练集中标记产品id的字段名称,该字段值必须是浮点数类型 (默认值: rating)
- predictionCol: 输出结果数据中最终用户的产品的评分预测值的字段名称 (默认值: prediction)
算法模型相关:
- implicitPrefs: 是否采用隐式评价模型,具体使用方式见上面算法介绍部分。 (boolean类型,默认值: false)
- alpha: 当采用隐式模型后,该参数表示训练数据中评分值对偏好的信任程度加持权重,具体公式见上面算法介绍部分。(>=0的实数,默认值: 1.0)
- maxIter: 迭代算法最大迭代次数 (>0的整数,默认值: 10)
- seed: 迭代算法的初始随机值的seed (long类型,默认值: 1994790107)
- nonnegative: 给最终因子向量的解增加约束,向量系数必须>=0,在某些评分必须是正的业务场景下使用。(boolean类型,默认值: false)
- rank: 因子向量的长度,即系数个数 (正整数,默认值:10)
- regParam: 正则化惩罚程度参数,具体使用方式见上面正则化相关介绍。(>=0的实数,默认值:0.1)
Spark实现相关:
- numUserBlocks: 并行时,每个分区包含多少个用户。(正整数,默认值:10)
- numItemBlocks: 并行时,每个分区包含多少个产品。(正整数,默认值:10)
model对象的成员
- coldStartStrategy: 冷启动策略 (默认值:nan)
可选项1. nan-当模型对象在transform时遇到训练数据中未出现过的产品或者用户时,返回NaN的预测分数;
可选项2. drop-当模型对象在transform时遇到训练数据中未出现过的产品或者用户时,返回的预测矩阵直接不包含该行或者该列,一般在评估模型性能时才设置为该选项。 - userFactors: 用户因子向量。
- itemFactors: 产品因子向量。
- recommendForAllItems(numUsers): 返回所有产品评分最高的
numUsers
个用户和其评分值。 - recommendForAllUsers(numItems): 返回所有用户最高评分的
numItems
个产品和其被评分值。 - recommendForItemSubset(itemIds, numUsers): 返回
itemIds
指定的产品评分最高的numUsers
个用户和其评分值。 - recommendForUserSubset(userIds, numItems): 返回
userIds
指定的用户最高评分的numItems
个产品和其被评分值。
例子
1 | case class Rating(userId: Int, movieId: Int, rating: Float) |