spark实现ALS算法-附scala代码

本文记录了使用scala语言在spark上实现ALS算法的相关内容,如有问题可以邮件(zhaoliang19960421@outlook.com)或微信(BestCoder_BestLife)与我联系

有关协同过滤的相关内容详见 spark实现协同过滤-附scala代码

在itemCF中以user-item-score矩阵为输入,将每个用户对每个商品的行为作为评分,将所有用户的评分作为一个商品的向量,利用该向量计算商品两两之间的相似度,来推荐该商品最相似的前N的其他商品。采用这样的方式依赖的是当两个item有相同的用户有行为时才会有相似度,否则就是0。

使用这样的方式会存在以下问题

  1. 推荐结果会出现马太效应,因为热门item会和所有的item都存在有共同行为的用户,对于所有的item而言都可以和热门计算相似度,热门item都有机会被推荐出来,热门item就会被越推越多
  2. 如果当user和item数量变多、用户显示/隐式行为很少时,user-item-score矩阵会变得很稀疏,计算两两相似度时只能靠很少的几个位置的数据来获得,可信度降低
  3. 当两个item没有共同使用的用户时,无法计算相似度
  4. 存储代价大,itemCF得到的是II/UU相似度,当user-item-score矩阵大小是m*n 时,需要保存的相似度矩阵是m*m、n*n

所以之后发展到了矩阵分解模型,即将m*n的user-item-score原始矩阵,通过分解的得到两个小的m*k、n*k 的小矩阵,通过拟合 m ∗ n = m ∗ k ⋅ n ∗ k m*n = m*k · n*k mn=mknk,这种思想相当于对原始的行为矩阵对每个user、item进行了向量化,每个向量的长度是k.
由于向量化矩阵是从全局的UI矩阵分解得到的,即使两个item在itemCF中无法计算相似度,向量化之后也可以被计算。类似的,由于user、item被表征到了同样长度的向量空间中,那么就可以直接计算ui相似度进行推荐。

1. itemCF是计算II相似度,通过用户有正向行为的商品推荐类似商品,即U2I2I
2. MF是将UI通过向量化到同一个空间中,直接计算User和item之间的相关新,即U2I

矩阵分解的具体方法在spark中采用的是ALS通过梯度下降的方式来训练降低两个小矩阵的乘积与原始矩阵的误差。

使用scala语言在spark中实现的ALS模型具体代码,实现了原始的ALS的u2i召回,i2u推荐,将item向量、user向量保存下来实现i2i召回,在线ANN的u2i召回

具体实现见代码

package *
import java.nio.charset.Charset

import com.google.common.hash.Hashing.murmur3_32
import *.Utils._
import *.SparkContextUtils._
import org.apache.spark.ml.recommendation._
import org.apache.spark.sql._
import org.apache.spark.sql.expressions.UserDefinedFunction
import org.apache.spark.sql.functions._

/**
 *
 *
 * 本代码已经做了脱敏处理,与原公司及业务无关,特此说明
 *
 *
 * @author zhaoliang19960421@outlook.com on 20220221
 *         基于org.apache.spark.ml.recommendation实现ALS算法
 *         从原始日志中计算得到user-item-score矩阵,通过ALS实现矩阵分解,得到als模型
 *         利用分解后的两个子矩阵,得到user向量、item向量
 *         利用als模型,实现u2i召回,i2u推荐
 *         利用item向量,实现i2i召回
 *         利用user向量,实现u2u计算相似度
 *         利用user向量、item向量,线上进行ANN实现U2I召回
 */
object ALS {
   
    val userColumn = "gaid" // user列名
    val userHasColumn = "user_hash" // user被hash之后的列名
    val itemColumn = "package_name" // item列名
    val itemHashColumn = "item_hash" // item被hash后的列名
    val userVecColumn = "userVec" // user向量
    val scoreColumn = "score" // user-item 相关度列名
    val itemVecColumn = "itemVec" // item向量
    val recommendNum = 100 // 相似个数
    val filterItemMinNum = 2 // 在计算得到user-item-score矩阵时,对脏数据进行过滤,需要每个用户最少对几个item有过行为
    val filterItemMaxNum = 10 // 同上&
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值