Spark之---【ML】算法库ALS简介

1. 协同过滤内容

  • 协同过滤
  • 显性反馈与隐性反馈
  • 缩放正则化参数
  • 冷启动问题

2. 协同过滤

协同过滤 通常用于推荐系统。 这些技术旨在填写用户项关联矩阵的缺失条目。 spark.ml 目前支持基于模型的协同过滤, 其中用户和产品由一小组可用于预测缺失条目的潜在因素描述。spark.ml 使用交替最小二乘( ALS) 算法来学习这些潜在因素。 实现中 spark.ml 包含以下参数:

  • numBlocks 是用户和项目将被分区为块以便并行计算的块数( 默认为 10)
  • rank 是模型中潜在因子的数量( 默认为 10,一般取10~1000,太小误差大;太大泛化能力差)
  • maxIter 是要运行的最大迭代次数( 默认为 10)
  • regParam 指定 ALS 中的正则化参数( 默认为 1.0)
  • implicitPrefs 指定是使用显式反馈 ALS 变体还是使用适用于隐式反馈数据的变体 ( 默认值 false 表示使用显式反馈)
  • alpha 是适用于 ALS 的隐式反馈变量的参数, 其控制偏好观察中的 基线置信度 ( 默认为 1.0)
  • nonnegative 指定是否对最小二乘使用非负约束( 默认为 false)
    注意: 基于 DataFrame 的 ALS API 目前仅支持userid和itemid 为整数。 user 和 item id 列支持其他数字类型, 但 id 必须在整数值范围内。

3. 显性反馈与隐性反馈

  • 基于矩阵分解的协同过滤的标准方法将用户项目矩阵中的条目视为用户对项目给出的显式偏好, 例如, 给予电影评级的用户。
  • 在许多现实世界的用例中, 通常只能访问隐式反馈( 例如, 观看, 点击, 购买, 喜欢,分享等)用于 spark.ml 处理此类数据的方法来自隐式反馈数据集的协作过滤。 本质上,这种方法不是直接对评级矩阵进行建模, 而是将数据视为代表强度的数字用户行为的观察( 例如点击次数或某人花在观看电影上的累积持续时间) 。 然后, 这些数字与观察到的用户偏好的置信水平相关, 而不是与项目的明确评级相关。 然后, 该模型试图找到可用于预测用户对项目的预期偏好的潜在因素。
  • 注意:这里有个问题就是ALS矩阵分解需要的是显示反馈,而在真实的生产环境,我们能够容易得到的是用户的隐性反馈。如何将用户的隐性反馈,等价的表征为用户显性反馈是我们值得关注的事情。

4.缩放正则化参数

我们 regParam 通过用户在更新用户因素时产生的评级数或在更新产品因子时收到的产品评级数来缩小正则化参数以解决每个最小二乘问题。 这种方法被命名为“ALS-WR”, 并在“ Netflix 奖的大规模并行协同过滤 ”一文中进行了讨论。 它 regParam 更少依赖于数据集的规模, 因此我们可以将从采样子集中学习的最佳参数应用于完整数据集, 并期望获得类似的性能

5.冷启动问题

在使用ALS进行预测时, 通常会遇到测试数据集中的用户或物品没有出现过, 这些用户或物品在训练模型期间不存在。 这通常发生在两种情况中:

  • 1.在生产中, 对于没有评级历史且未对模型进行过训练的新用户或物品( 这是“冷启动问题”)
  • 2.在交叉验证期间, 数据在训练和评估集之间分配。 当 Spark 中的使用简单随机拆分为CrossValidator 或者 TrainValidationSplit,它实际上是非常容易遇到的测试集中的用户或物品,在训练集中从来没有出现过。
    解决思路:
  • 默认情况下,模型会将在训练时没有出现过的用户或者物品,Spark会在ALSModel.Transform期间,将预测结果指定为NaN。这在生产系统中很有用,因为它表明这是一个新的用户或物品,因此系统可以针对这种情况,可以在逻辑层设计对应的逻辑,来处理新用户或者新物品的状况。但是, 这在交叉验证期间是不合理的的, 因为任何 NaN 预测值都将导致模型在评估时的不准确( 例如在使用时 RegressionEvaluator) 。 这使得模型的选择变得不容易实现,甚至会出错。
  • 针对上述的问题Spark 提供了将coldStartStrategy 参数设置为“drop”的方式, 就是删除 DataFrame中包含NaN值的预测中的任何行。然后将根据非 NaN数据对模型进行评估,并且该评估是有效的。以下示例说明了此参数的用法。
  • 注意: 目前支持的冷启动策略是“nan”( 上面提到的默认行为) 和“drop”。 将来可能会支持进一步的策略。
    这里使用的电影数据集进行的演示,需要的可以自行下载
from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.recommendation import ALS
from pyspark.sql import Row

lines = spark.read.text("data/mllib/als/sample_movielens_ratings.txt").rdd
parts = lines.map(lambda row: row.value.split("::"))
ratingsRDD = parts.map(lambda p: Row(userId=int(p[0]), movieId=int(p[1]),
                                     rating=float(p[2]), timestamp=long(p[3])))
ratings = spark.createDataFrame(ratingsRDD)
(training, test) = ratings.randomSplit([0.8, 0.2])

# 在训练集上构建推荐系统模型
# 在这里我们设置了冷启动的策略为‘drop’,以保证我们不会得到一个‘NAN’的预测结果
als = ALS(maxIter=5, regParam=0.01, userCol="userId", itemCol="movieId", ratingCol="rating",
          coldStartStrategy="drop")
model = als.fit(training)

# 在测试集上评估模型,标准为RMSE
predictions = model.transform(test)
evaluator = RegressionEvaluator(metricName="rmse", labelCol="rating",
                                predictionCol="prediction")
rmse = evaluator.evaluate(predictions)
print("Root-mean-square error = " + str(rmse))

# 为每一个用户推荐10个电影
userRecs = model.recommendForAllUsers(10)
# 为每个电影推荐10个用户
movieRecs = model.recommendForAllItems(10)

# 为指定的一组用户生成top10个电影推荐
users = ratings.select(als.getUserCol()).distinct().limit(3)
userSubsetRecs = model.recommendForUserSubset(users, 10)
# 为指定的一组电影生成top10个用户推荐
movies = ratings.select(als.getItemCol()).distinct().limit(3)
movieSubSetRecs = model.recommendForItemSubset(movies, 10)

6.总结

本篇博客是使用的sparkML库,底层的数据结构使用的DataFrame,在使用对应的包的时候要注意区分,这里博主比较常用的是Python,所以给出的代码也是Python代码,如果有其他的需求或者不同的技术栈,可以参考官网!
这里要提一句的是,spark官方实现的ALS由于调度方面的问题,在训练的时候非常的慢,如果对效率有要求的,这里需要自己去自己去实现一下,在后续的更新中,也会给出一些自己实现的版本。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值