Spark2.0 协同过滤推荐

ALS矩阵分解

http://blog.csdn.net/oucpowerman/article/details/49847979 
http://www.open-open.com/lib/view/open1457672855046.html 
       一个的打分矩阵 A 可以用两个小矩阵和的乘积来近似,描述一个人的喜好经常是在一个抽象的低维空间上进行的,并不需要把其喜欢的事物一一列出。再抽象一些,把人们的喜好和电影的特征都投到这个低维空间,一个人的喜好映射到了一个低维向量,一个电影的特征变成了纬度相同的向量,那么这个人和这个电影的相似度就可以表述成这两个向量之间的内积。 
       我们把打分理解成相似度,那么“打分矩阵A(m?n)”就可以由“用户喜好特征矩阵U(m?k)”和“产品特征矩阵V(n?k)”的乘积。 
       矩阵分解过程中所用的优化方法分为两种:交叉最小二乘法(alternative least squares)和随机梯度下降法(stochastic gradient descent)。

参数选取

    • 分块数:分块是为了并行计算,默认为10。
    • 正则化参数:默认为1。
    • 秩:模型中隐藏因子的个数
    • 显示偏好信息-false,隐式偏好信息-true,默认false(显示)
    • alpha:只用于隐式的偏好数据,偏好值可信度底线。
    • 非负限定
    • numBlocks is the number of blocks the users and items will be 
      partitioned into in order to parallelize computation (defaults to 
      10).
    • rank is the number of latent factors in the model (defaults to 10).
    • maxIter is the maximum number of iterations to run (defaults to 10).
    • regParam specifies the regularization parameter in ALS (defaults to 1.0).
    • implicitPrefs specifies whether to use the explicit feedback ALS variant or one adapted for implicit feedback data (defaults to false 
      which means using explicit feedback).
    • alpha is a parameter applicable to the implicit feedback variant of ALS that governs the baseline confidence in preference 
      observations (defaults to 1.0).
    • nonnegative specifies whether or not to use nonnegative constraints for least squares (defaults to false).
 ALS als = new ALS()
          .setMaxIter(10)//最大迭代次数,设置太大发生java.lang.StackOverflowError
          .setRegParam(0.16)//正则化参数
          .setAlpha(1.0)
          .setImplicitPrefs(false)
          .setNonnegative(false)
          .setNumBlocks(10)
          .setRank(10)
          .setUserCol("userId")
          .setItemCol("movieId")
          .setRatingCol("rating");

需要注意的问题: 
对于用户和物品项ID ,基于DataFrame API 只支持integers,因此最大值限定在integers范围内。

The DataFrame-based API for ALS currently only supports integers for
user and item ids. Other numeric types are supported for the user and
item id columns, but the ids must be within the integer value range.
//循环正则化参数,每次由Evaluator给出RMSError
      List<Double> RMSE=new ArrayList<Double>();//构建一个List保存所有的RMSE
      for(int i=0;i<20;i++){//进行20次循环
          double lambda=(i*5+1)*0.01;//RegParam按照0.05增加
          ALS als = new ALS()
          .setMaxIter(5)//最大迭代次数
          .setRegParam(lambda)//正则化参数
          .setUserCol("userId")
          .setItemCol("movieId")
          .setRatingCol("rating");
          ALSModel model = als.fit(training);
          // Evaluate the model by computing the RMSE on the test data
          Dataset<Row> predictions = model.transform(test);
          //RegressionEvaluator.setMetricName可以定义四种评估器
          //"rmse" (default): root mean squared error
          //"mse": mean squared error
          //"r2": R^2^ metric
          //"mae": mean absolute error
          RegressionEvaluator evaluator = new RegressionEvaluator()
          .setMetricName("rmse")//RMS Error
          .setLabelCol("rating")
          .setPredictionCol("prediction");
          Double rmse = evaluator.evaluate(predictions);
          RMSE.add(rmse);
          System.out.println("RegParam "+0.01*i+" RMSE " + rmse+"\n");
      }
      //输出所有结果
      for (int j = 0; j < RMSE.size(); j++) {
          Double lambda=(j*5+1)*0.01;
          System.out.println("RegParam= "+lambda+"  RMSE= " + RMSE.get(j)+"\n");
    }
通过设计一个循环,可以研究最合适的参数,部分结果如下:
RegParam= 0.01  RMSE= 1.956
RegParam= 0.06  RMSE= 1.166
RegParam= 0.11  RMSE= 0.977
RegParam= 0.16  RMSE= 0.962//具备最小的RMSE,参数最合适
RegParam= 0.21  RMSE= 0.985
RegParam= 0.26  RMSE= 1.021
RegParam= 0.31  RMSE= 1.061
RegParam= 0.36  RMSE= 1.102
RegParam= 0.41  RMSE= 1.144
RegParam= 0.51  RMSE= 1.228
RegParam= 0.56  RMSE= 1.267
RegParam= 0.61  RMSE= 1.300
//将RegParam固定在0.16,继续研究迭代次数的影响
输出如下的结果,在单机环境中,迭代次数设置过大,会出现一个java.lang.StackOverflowError异常。是由于当前线程的栈满了引起的。
numMaxIteration= 1  RMSE= 1.7325
numMaxIteration= 4  RMSE= 1.0695
numMaxIteration= 7  RMSE= 1.0563
numMaxIteration= 10  RMSE= 1.055
numMaxIteration= 13  RMSE= 1.053
numMaxIteration= 16  RMSE= 1.053
//测试Rank隐含语义个数
Rank =1  RMSErr = 1.1584
Rank =3  RMSErr = 1.1067
Rank =5  RMSErr = 0.9366
Rank =7  RMSErr = 0.9745
Rank =9  RMSErr = 0.9440
Rank =11  RMSErr = 0.9458
Rank =13  RMSErr = 0.9466
Rank =15  RMSErr = 0.9443
Rank =17  RMSErr = 0.9543

//可以用SPARK-SQL自己定义评估算法(如下面定义了一个平均绝对值误差计算过程)
// Register the DataFrame as a SQL temporary view
predictions.createOrReplaceTempView("tmp_predictions");
Dataset<Row> absDiff=spark.sql("select abs(prediction-rating) as diff from tmp_predictions");
absDiff.createOrReplaceTempView("tmp_absDiff");
spark.sql("select mean(diff) as absMeanDiff from tmp_absDiff").show();      

完整代码

可以在 http://spark.apache.org/docs/latest/ml-collaborative-filtering.html找到

package my.spark.ml.practice.classification;

import org.apache.spark.api.java.function.Function;
import org.apache.spark.ml.evaluation.RegressionEvaluator;
import org.apache.spark.ml.recommendation.ALS;
import org.apache.spark.ml.recommendation.ALSModel;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;

public class myCollabFilter2 {  

    public static void main(String[] args) {
        SparkSession spark=SparkSession
                .builder()
                .appName("CoFilter")
                .master("local[4]")
                .config("spark.sql.warehouse.dir","file///:G:/Projects/Java/Spark/spark-warehouse" )
                .getOrCreate();

        String path="G:/Projects/CgyWin64/home/pengjy3/softwate/spark-2.0.0-bin-hadoop2.6/"
                + "data/mllib/als/sample_movielens_ratings.txt";

        //屏蔽日志
                Logger.getLogger("org.apache.spark").setLevel(Level.WARN);
                Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF);
        //-------------------------------1.0 准备DataFrame----------------------------
        //..javaRDD()函数将DataFrame转换为RDD
        //然后对RDD进行Map 每一行String->Rating
        JavaRDD<Rating> ratingRDD=spark.read().textFile(path).javaRDD()
                .map(new Function<String, Rating>() {

                    @Override
                    public Rating call(String str) throws Exception {
                        return Rating.parseRating(str);
                    }
                });
        //System.out.println(ratingRDD.take(10).get(0).getMovieId());

        //由JavaRDD(每一行都是一个实例化的Rating对象)和Rating Class创建DataFrame
        Dataset<Row> ratings=spark.createDataFrame(ratingRDD, Rating.class);
        //ratings.show(30);

        //将数据随机分为训练集和测试集
        double[] weights=new double[] {0.8,0.2};
        long seed=1234;
        Dataset<Row> [] split=ratings.randomSplit(weights, seed);
        Dataset<Row> training=split[0];
        Dataset<Row> test=split[1];         

        //------------------------------2.0 ALS算法和训练数据集,产生推荐模型-------------
        for(int rank=1;rank<20;rank++)
        {
            //定义算法
            ALS als=new ALS()
                    .setMaxIter(5)////最大迭代次数,设置太大发生java.lang.StackOverflowError
                    .setRegParam(0.16)
                    .setUserCol("userId")
                    .setRank(rank)
                    .setItemCol("movieId")
                    .setRatingCol("rating");
            //训练模型
            ALSModel model=als.fit(training);
            //---------------------------3.0 模型评估:计算RMSE,均方根误差---------------------
            Dataset<Row> predictions=model.transform(test);
            //predictions.show();
            RegressionEvaluator evaluator=new RegressionEvaluator()
                    .setMetricName("rmse")
                    .setLabelCol("rating")
                    .setPredictionCol("prediction");
            Double rmse=evaluator.evaluate(predictions);
            System.out.println("Rank =" + rank+"  RMSErr = " + rmse);
        }
    }
}

原文地址:https://www.cnblogs.com/itboys/p/8320723.html

时间: 2024-11-02 16:12:39

Spark2.0 协同过滤推荐的相关文章

基于用户的协同过滤推荐算法原理和实现

在推荐系统众多方法中,基于用户的协同过滤推荐算法是最早诞生的,原理也较为简单.该算法1992年提出并用于邮件过滤系统,两年后1994年被 GroupLens 用于新闻过滤.一直到2000年,该算法都是推荐系统领域最著名的算法. 本文简单介绍基于用户的协同过滤算法思想以及原理,最后基于该算法实现园友的推荐,即根据你关注的人,为你推荐博客园中其他你有可能感兴趣的人. 基本思想 俗话说"物以类聚.人以群分",拿看电影这个例子来说,如果你喜欢<蝙蝠侠>.<碟中谍>.&l

Slope One 协同过滤 推荐算法

Slope one  是一个简单,效率较高的协同过滤推荐算法. Slope One 算法是由 Daniel Lemire 教授在 2005 年提出.距今已经10年.   基于如下五点被设计出来: 1. 算法容易实现和维护 2. 对新的评分应该立即给予响应 3. 查询速度要快(虽然可能以牺牲存储量为代价) 4. 对新的用户也要能给出有效的推荐 5. 精度上要有竞争力 slope one用于推荐,其特点是算法逻辑简单,实现容易,算法复杂度低. 像是刚接触推荐系统的朋友可以先采用这种算法来快速实现推荐

协同过滤推荐(第1周)

说明:文章为初学者看推荐系统(蒋凡),结合网上资料做的笔记,不保证其正确性~ 一.首先当前的主流推荐方法有: 1.  协同过滤推荐: 2.  基于内容的推荐: 3.  基于知识的推荐: 4.  混合推荐: (注:学习过程不必特意将他们区分开,由他们的推荐公式知道他们的缺陷,混合使用) 1.  协同过滤(CF collaborative Filtering): 1-1:基于用户的最近邻推荐: 1)  (我理解的定义)从"协同过滤"四字知道其指的是:因为想到推荐,我们都是想到问用户喜欢什么

SimRank协同过滤推荐算法

在协同过滤推荐算法总结中,我们讲到了用图模型做协同过滤的方法,包括SimRank系列算法和马尔科夫链系列算法.现在我们就对SimRank算法在推荐系统的应用做一个总结. 1. SimRank推荐算法的图论基础 SimRank是基于图论的,如果用于推荐算法,则它假设用户和物品在空间中形成了一张图.而这张图是一个二部图.所谓二部图就是图中的节点可以分成两个子集,而图中任意一条边的两个端点分别来源于这两个子集.一个二部图的例子如下图.从图中也可以看出,二部图的子集内部没有边连接.对于我们的推荐算法中的

矩阵分解在协同过滤推荐算法中的应用

在协同过滤推荐算法总结中,我们讲到了用矩阵分解做协同过滤是广泛使用的方法,这里就对矩阵分解在协同过滤推荐算法中的应用做一个总结.(过年前最后一篇!祝大家新年快乐!明年的目标是写120篇机器学习,深度学习和NLP相关的文章) 1. 矩阵分解用于推荐算法要解决的问题 在推荐系统中,我们常常遇到的问题是这样的,我们有很多用户和物品,也有少部分用户对少部分物品的评分,我们希望预测目标用户对其他未评分物品的评分,进而将评分高的物品推荐给目标用户.比如下面的用户物品评分表: 用户\物品 物品1 物品2 物品

机器学习算法原理解析——协同过滤推荐

1. CF协同过滤推荐算法原理及应用 1.1 概述 什么是协同过滤(Collaborative Filtering,简称CF)? 首先想一个简单的问题,如果你现在想看个电影,但你不知道具体看哪部,你会怎么做? 大部分的人会问问周围id朋友,看看最近有什么好看的电影推荐,而我们一般更倾向于从口味比较类似的朋友那里得到推荐.这就是协同过滤的核心思想. 协同过滤算法又分为基于用户的协同过滤算法和基于物品的协同过滤算法. 1.2 案例需求 如下数据是各用户对各文档的偏好: 用户/文档 文档A 文档B 文

协同过滤推荐算法的原理及实现

一.协同过滤算法的原理及实现 协同过滤推荐算法是诞生最早,并且较为著名的推荐算法.主要的功能是预测和推荐.算法通过对用户历史行为数据的挖掘发现用户的偏好,基于不同的偏好对用户进行群组划分并推荐品味相似的商品.协同过滤推荐算法分为两类,分别是基于用户的协同过滤算法(user-based collaboratIve filtering),和基于物品的协同过滤算法(item-based collaborative filtering).简单的说就是:人以类聚,物以群分.下面我们将分别说明这两类推荐算法

什么是协同过滤推荐算法?

剖析千人千面的大脑——推荐引擎部分,其中这篇是定位:对推荐引擎中的核心算法:协同过滤进行深挖. 首先,千人千面融合各种场景,如搜索,如feed流,如广告,如风控,如策略增长,如购物全流程等等:其次千人千面的大脑肯定是内部的推荐引擎,这里有诸多规则和算法在实现对上述各个场景进行“细分推荐排序”:最后是推荐引擎的算法又以“协同过滤”为最核心.最主流热门,也是当下众多内容型.电商型.社交工具.分发型的基础. 由于协同过滤的算法介绍,网上也蛮多但片段化.要么侧重讲“原理流程”,这个占了4成:要么讲算法公

推荐算法-协同过滤推荐算法

layout: post title: "推荐算法-协同过滤推荐算法" date: 2020-4-13 9:00:00 categories: [Algorithm] excerpt: "协同过滤推荐算法简介,参考https://zhuanlan.zhihu.com/p/40463528" 协同过滤推荐算法步骤 1.收集用户偏好 推测用户的喜好就要收集用户的信息,用户收藏的类别,评论,下载,转发这些信息可以数字化,作为用户信息二维矩阵的变量. 2.用户数据的减噪和归