基于Spark的协同过滤音乐推荐(python源码分析)

本文详细介绍了基于Spark的协同过滤音乐推荐的实现过程,从Spark的基本概念到mllib推荐算法,特别是如何使用pyspark.mllib.recommendation.ALS进行矩阵分解。通过设置不同参数如rank、iterations和lambda_训练模型,并对模型进行预测,以完成音乐推荐。需要注意,由于矩阵分解的随机初始化,多次运行可能会得到不同的推荐结果。
摘要由CSDN通过智能技术生成

因为要进行大数据场景下利用Spark做音乐推荐,所以记录一下学习Spark的过程和实验过程。

一 对Spark整体上的认识

Spark是一个分布式计算引擎,将大量的计算任务分发到计算结点,实现分布式计算,和hadoop不同的是,Spark计算的中间结果存储在内存中,所以同等配置机器情况下,Spark的运算速度比hadoop块很多倍。Spark的基本概念包括:

Application:用户编写的Spark程序

RDD:弹性分布式数据集,可以看成是数据在分布式内存上的表示

Job(作业):一个Job包含多个RDD及应用于RDD上的各种操作

Executor(执行者):负责执行各种Task(任务)的进程

Task(任务): 运行在Executor上的工作单元

Worker(工作节点):集群中的具体执行计算任务的结点

Driver(任务控制节点):Driver负责提交Job,转换为Task,在Executor进程间协调Task调度。

SparkContext: 用户程序和集群管理器交互的接口

如下图,任务控制结点(Driver)创建SparkContext,由SparkContext向集群管理器(Cluster Manager)申请计算资源,创建执行者进程(Executor),然后将任务(Task)被分配到2个计算结点上(Worker Node),各个计算节点还需要和存储系统HDFS,HIVE进行交互,读取数据或者写入数据。

图9-5-Spark运行架构

下图表明了Spark中各种概念之间的关系,一个任务控制节点可以创建多个作业,每个作业包含多个执行阶段,每个阶段包含多个任务。执行用户编写的Spark程序时,会创建一个任务控制节点,申请计算资源,分发程序代码和数据,各个计算节点的执行者开始分阶段执行不同的任务。

图9-6-Spark中各种概念之间的相互关系

Spark的具体运行过程如下图,任务控制节点创建了SparkContext对象,其负责创建RDD,构建DAG图(有向无环图,反映了RDD之间的关系),然后向集群管理器申请资源,集群管理器分配计算节点 ,计算结点向SparkContext申请任务,SparkContext将DAG图分解成任务集合,在将任务集合分配到不同的计算结点上去 。计算节点上的执行者进程执行任务,任务完成后通知SparkContext,写入数据,释放资源。

图9-7-Spark运行基本流程图

二 spark mllib recommendation

Spark的推荐算法只有基于矩阵分解的协同过滤算法,即将m个用户和n个物品组成的评分矩阵M分解成低维矩阵A和B的內积。其矩阵分解算法是FunkSVD。

Spark MLlib推荐算法python对应的接口都在pyspark.mllib.recommendation包中,这个包有三个类,Rating, MatrixFactorizationModel和ALS。

Rating类如下所示,代表用户的评分记录,即用户id,物品id,评分

class Rating(namedtuple("Rating", ["user", "product", "rating"])):
    """
    Represents a (user, product, rating) tuple.
    >>> r = Rating(1, 2, 5.0)
    >>> (r.user, r.product, r.rating)
    (1, 2, 5.0)
    >>> (r[0], r[1], r[2])
    (1, 2, 5.0)
    .. versionadded:: 1.2.0
    """

    def __reduce__(self):
        return Rating, (int(self.user), int(self.product), float(self.rating))

**ALS类中封装了使用交替最小二乘法,使用Rating类提供的元组进行模型训练的方法。**FunkSVD进行矩阵分解的目标优化函数使用的是ALS。ALS类中有train和trainImplicit两个方法,train方法是直接使用评分矩阵进行矩阵分解,而trainImplicit使用了隐式用户反馈数据来训练模型。本文只考虑使用评分矩阵进行矩阵分解。

train方法的参数有:

1) ratings : 输入评分矩阵对应的RDD。

2) rank : 矩阵分解时对应的低维的维数。维数越大,算法运行时间和空间需求越大,通常取10-200。

3) iterations :在矩阵分解用交替最小二乘法求解时,进行迭代的最大次数。这个值取决于评分矩阵的维度,以及评分矩阵的系数程度。一般来说,不需要太大,比如5-20次即可。默认值是5。

4) lambda: 在 python接口中使用的是lambda_,原因是lambda是Python的保留字。这个值即为FunkSVD分解时对应的正则化系数。主要用于控制模型的拟合程度,增强模型泛化能力。取值越大,则正则化惩罚越强。大型推荐系统一般需要调参得到合适的值。

class ALS(object):
    """Alternating Least Squares matrix factorization
    .. versionadded:: 0.9.0
    """
	....omitted...
    @classmethod
    @since("0.9.0")
    def train(cls, ratings, rank, iterations=5, lambda_=0.01, blocks=-1, nonnegative=False,
              seed=None):
        """
        Train a matrix factorization model given an RDD of ratings by users
        for a subset of products. The ratings matrix is approximated as the
        product of two lower-rank matrices of a given rank (number of
        features). To solve for these features, ALS is run iteratively with
        a configurable level of parallelism.
        :param ratings:
          RDD of `Rating` or (userID, productID, rating) tuple.
        :param rank:
          Number of features to use (also referred to as the number of latent factors).
        :param iterations:
          Number of iterations of ALS.
          (default: 5)
        :param lambda_:
          Regularization parameter.
          (default: 0.01)
        :param blocks:
          Number of blocks used to parallelize the computation. A value
          of -1 will use an auto-configured number of blocks.
          (default: -1)
        :param nonnegative:
          A value of True will solve least-squares with nonnegativity
          constraints.
          (default: False)
        :param seed:
          Random seed for initial matrix factorization model. A value
          of None will use system time as the seed.
          (default: None)
        """
        model = callMLlibFunc("trainALSModel", cls._prepare(ratings), rank, iterations,
                              lambda_, blocks, nonnegative, seed)
        return MatrixFactorizationModel(model)

    @classmethod
    @since("0.9.0")
    def trainImplicit(cls, ratings, rank, iterations=5, lambda_=0.01, blocks=-1, alpha=0.01,
                      nonnegative=False, seed=None):
      
  • 7
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在IDEA中基于Spark实现协同过滤推荐,可以按照以下步骤进行: 1. 导入Spark相关依赖和数据集 ```scala import org.apache.spark.sql.SparkSession val spark = SparkSession.builder() .appName("Collaborative Filtering Example") .getOrCreate() val ratings = spark.read.format("csv") .option("header", "true") .option("inferSchema", "true") .load("ratings.csv") .drop("timestamp") ``` 其中,`ratings.csv`是包含用户评分数据的文件,每行包括`userId`、`movieId`和`rating`三列,用逗号分隔。 2. 划分训练集和测试集 ```scala import org.apache.spark.ml.recommendation.{ALS, ALSModel} import org.apache.spark.ml.evaluation.RegressionEvaluator val Array(training, test) = ratings.randomSplit(Array(0.8, 0.2)) ``` 将数据集划分为训练集和测试集,其中80%用于训练,20%用于测试。 3. 训练模型 ```scala val als = new ALS() .setMaxIter(5) .setRegParam(0.01) .setUserCol("userId") .setItemCol("movieId") .setRatingCol("rating") val model = als.fit(training) ``` 使用ALS算法训练模型,其中`setMaxIter`设置迭代次数,`setRegParam`设置正则化参数,`setUserCol`、`setItemCol`和`setRatingCol`分别设置用户ID、物品ID和评分列名。 4. 预测评分 ```scala val predictions = model.transform(test) val evaluator = new RegressionEvaluator() .setMetricName("rmse") .setLabelCol("rating") .setPredictionCol("prediction") val rmse = evaluator.evaluate(predictions) println(s"Root-mean-square error = $rmse") ``` 将测试集输入模型进行预测,并使用RMSE指标评估预测效果。 5. 使用模型进行推荐 ```scala val userRecs = model.recommendForAllUsers(10) val movieRecs = model.recommendForAllItems(10) ``` 使用训练好的模型生成用户和物品的推荐结果,其中`recommendForAllUsers`和`recommendForAllItems`分别表示为所有用户和所有物品生成推荐结果,数字10表示每个用户或物品生成的推荐数目。 以上就是基于Spark实现协同过滤推荐的一个简单示例。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值