Spark ALS 算法给出了太多的零因子

Posted

技术标签:

【中文标题】Spark ALS 算法给出了太多的零因子【英文标题】:Spark ALS algorithm gives too many zero factors 【发布时间】:2019-12-31 15:10:11 【问题描述】:

我们在 spark 2.2.1 中使用 ALS 来计算用户嵌入和项目嵌入。我们的实验样本包含 120 亿个实例,被点击的实例被标记为正例,否则被标记为负例。

在使用用户嵌入和项目嵌入的乘积评估 AUC 时,我们发现 AUC 指标在相同的训练数据和相同的参数上并不稳定。在检查嵌入后,我们发现即使用户点击了一些异常的项目,ALS 也可能给出零因子。

有什么想法吗?谢谢你的帮助。 这是我们的代码

val hivedata = sc.sql(sqltext).select(id,dpid,score).coalesce(numPartitions)
val predataItem =  hivedata.rdd.map(r=>(r._1._1,(r._1._2,r._2.sum)))
  .groupByKey().zipWithIndex()
  .persist(StorageLevel.MEMORY_AND_DISK_SER)
val predataUser = predataItem.flatMap(r=>r._1._2.map(y=>(y._1,(r._2.toInt,y._2))))
  .aggregateByKey(zeroValueArr,numPartitions)((a,b)=> a += b,(a,b)=>a ++ b).map(r=>(r._1,r._2.toIterable))
  .zipWithIndex().persist(StorageLevel.MEMORY_AND_DISK_SER)
val trainData = predataUser.flatMap(x => x._1._2.map(y => (x._2.toInt, y._1, y._2.toFloat)))
  .setName(trainDataName).persist(StorageLevel.MEMORY_AND_DISK_SER)

case class ALSData(user:Int, item:Int, rating:Float) extends Serializable
val ratingData = trainData.map(x => ALSData(x._1, x._2, x._3)).toDF()
    val als = new ALS
    val paramMap = ParamMap(als.alpha -> 25000).
      put(als.checkpointInterval, 5).
      put(als.implicitPrefs, true).
      put(als.itemCol, "item").
      put(als.maxIter, 60).
      put(als.nonnegative, false).
      put(als.numItemBlocks, 600).
      put(als.numUserBlocks, 600).
      put(als.regParam, 4.5).
      put(als.rank, 25).
      put(als.userCol, "user")
    als.fit(ratingData, paramMap)

【问题讨论】:

请分享代码。我们也有类似的问题,但这是由于不正确的特征映射 你能提供更多关于不正确的特征映射的细节吗?谢谢。 @partha_devArch 请检查用户和项目列映射。而且,我在您的代码中没有看到 als 的评分列 【参考方案1】:

有两个原因: 1.当没有正样本时,项向量全为零。 2. 输入数据可能是不确定的。 related github issues

【讨论】:

以上是关于Spark ALS 算法给出了太多的零因子的主要内容,如果未能解决你的问题,请参考以下文章

交替最小二乘+ALS+推荐+Spark

ALS推荐算法在Spark上的优化

spark实现ALS算法-附scala代码

spark实现ALS算法-附scala代码

基于Spark的Als算法+自迭代+Spark2.0新写法

Machine Learning With Spark学习笔记(在10万电影数据上训练使用推荐模型)