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()//最大迭代次数,设置太大发生java.lang.StackOverflowError
.setRegParam(0.16)//正则化参数
.setAlpha(1.0)
.setImplicitPrefs(false)
.setNonnegative(false)
.setNumBlocks()
.setRank()
.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=;i<;i++){//进行20次循环
double lambda=(i*+)*0.01;//RegParam按照0.05增加
ALS als = new ALS()
.setMaxIter()//最大迭代次数
.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 = ; j < RMSE.size(); j++) {
Double lambda=(j*+)*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= RMSE= 1.7325
numMaxIteration= RMSE= 1.0695
numMaxIteration= RMSE= 1.0563
numMaxIteration= RMSE= 1.055
numMaxIteration= RMSE= 1.053
numMaxIteration= RMSE= 1.053
//测试Rank隐含语义个数
Rank = RMSErr = 1.1584
Rank = RMSErr = 1.1067
Rank = RMSErr = 0.9366
Rank = RMSErr = 0.9745
Rank = RMSErr = 0.9440
Rank = RMSErr = 0.9458
Rank = RMSErr = 0.9466
Rank = RMSErr = 0.9443
Rank = 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=;
Dataset<Row> [] split=ratings.randomSplit(weights, seed);
Dataset<Row> training=split[];
Dataset<Row> test=split[]; //------------------------------2.0 ALS算法和训练数据集,产生推荐模型-------------
for(int rank=;rank<;rank++)
{
//定义算法
ALS als=new ALS()
.setMaxIter()////最大迭代次数,设置太大发生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);
}
}
}
Spark2.0 协同过滤推荐的更多相关文章
- Spark2.0协同过滤与ALS算法介绍
ALS矩阵分解 一个 的打分矩阵 A 可以用两个小矩阵和的乘积来近似,描述一个人的喜好经常是在一个抽象的低维空间上进行的,并不需要把其喜欢的事物一一列出.再抽象一些,把人们的喜好和电影的特征都投到这个 ...
- 基于物品的协同过滤推荐算法——读“Item-Based Collaborative Filtering Recommendation Algorithms” .
ligh@local-host$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.3 基于物品的协同过滤推荐算法--读"Item-Based ...
- SimRank协同过滤推荐算法
在协同过滤推荐算法总结中,我们讲到了用图模型做协同过滤的方法,包括SimRank系列算法和马尔科夫链系列算法.现在我们就对SimRank算法在推荐系统的应用做一个总结. 1. SimRank推荐算法的 ...
- SparkMLlib—协同过滤推荐算法,电影推荐系统,物品喜好推荐
SparkMLlib-协同过滤推荐算法,电影推荐系统,物品喜好推荐 一.协同过滤 1.1 显示vs隐式反馈 1.2 实例介绍 1.2.1 数据说明 评分数据说明(ratings.data) 用户信息( ...
- Mahout之(二)协同过滤推荐
协同过滤 —— Collaborative Filtering 协同过滤简单来说就是根据目标用户的行为特征,为他发现一个兴趣相投.拥有共同经验的群体,然后根据群体的喜好来为目标用户过滤可能感兴趣的内容 ...
- 基于MapReduce的(用户、物品、内容)的协同过滤推荐算法
1.基于用户的协同过滤推荐算法 利用相似度矩阵*评分矩阵得到推荐列表 已经推荐过的置零 2.基于物品的协同过滤推荐算法 3.基于内容的推荐 算法思想:给用户推荐和他们之前喜欢的物品在内容上相似的物品 ...
- 推荐系统| ② 离线推荐&基于隐语义模型的协同过滤推荐
一.离线推荐服务 离线推荐服务是综合用户所有的历史数据,利用设定的离线统计算法和离线推荐算法周期性的进行结果统计与保存,计算的结果在一定时间周期内是固定不变的,变更的频率取决于算法调度的频率. 离线推 ...
- Spark ML协同过滤推荐算法
一.简介 协同过滤算法[Collaborative Filtering Recommendation]算法是最经典.最常用的推荐算法.该算法通过分析用户兴趣,在用户群中找到指定用户的相似用户,综合这些 ...
- 基于局部敏感哈希的协同过滤推荐算法之E^2LSH
需要代码联系作者,不做义务咨询. 一.算法实现 基于p-stable分布,并以‘哈希技术分类’中的分层法为使用方法,就产生了E2LSH算法. E2LSH中的哈希函数定义如下: 其中,v为d维原始数据, ...
随机推荐
- OSX活动监视器关闭spotlight 、mds_stores等进程
如果是机械盘,spotlight .mds_stores严重影响使用体验 今天早上一开机,设备速度慢的受不了,随便打开一个应用都几分钟.通过top查看,CPU剩余90%以上.所以并不是CPU不足导致. ...
- 使用pjsip传输已经编码的视频
http://blog.chinaunix.net/uid-15063109-id-4445165.html ————————————————————————————————————————————— ...
- HeadFisrt 设计模式03 装饰者
类应该对扩展开放, 对修改关闭. 所谓装饰者模式, 是指用其他的类来装饰某个类, 装饰者说白了就是使用 has-a 来代替 is-a 隐喻 咖啡店, 有很多种咖啡, 咖啡里还要增加一些 milk, 面 ...
- 你不知道的JavaScript学习笔记1——作用域
处理程序三要素: 引擎:编译与执行过程. 编译器:语法分析与代码生成等. 作用域:收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权 ...
- centos7安装avahi
sudo yum install avahi sudo yum install avahi-tools 转自: http://unix.stackexchange.com/questions/1829 ...
- Linxu内核参数详解
#表示SYN队列的长度,默认为1024,加大队列长度,可以容纳更多等待连接的网络连接数. net.ipv4.tcp_max_syn_backlog = 65536 #每个网络接口接收数据包的速率比内核 ...
- Tomcat服务器的安装与配置
安装 输入网址进入Tomcat的官网 在左边导航栏选择对应下载的版本 下载安装包形式 下载并解压到我们欲放入的目录中 配置 ...
- 输入一个long类型的整数,输出一个以金融格式表示的字符串
package test; public class Test { public static void main(String[] args) { System.out.println(yuan(1 ...
- centos7 docker install
env: os :centos 7 vmware steps: 1.yum -y install docker after installed ,using docker version cmd ...
- ORA-01078错误解决办法
ORA-01078: failure in processing system parameters & LRM-00109: could not open parameter file 安装 ...