基于Spark的电影推荐系统(推荐系统~4)
第四部分-推荐系统-模型训练
- 本模块基于第3节 数据加工得到的训练集和测试集数据 做模型训练,最后得到一系列的模型,进而做 预测。
- 训练多个模型,取其中最好,即取RMSE(均方根误差)值最小的模型
说明几点
1.ALS 算法不需要自己实现,Spark MLlib 已经实现好了,可以自己 跟源码学习
花时间钻研,动手写,写代码 翻译论文 写博客 多下功夫
2. 最新http://spark.apache.org/docs/latest/ml-guide.html
3. spark1.6.3
spark.mllib contains the original API built on top of RDDs.
spark.ml provides higher-level API built on top of DataFrames for constructing ML pipelines.
==》 我们采用spark.mllib ,也就是基于RDD之上来构建
学习:http://spark.apache.org/docs/1.6.3/mllib-collaborative-filtering.html#collaborative-filtering
import org.apache.spark.mllib.recommendation.ALS
import org.apache.spark.mllib.recommendation.MatrixFactorizationModel
import org.apache.spark.mllib.recommendation.Rating
// Load and parse the data
val data = sc.textFile("data/mllib/als/test.data")
val ratings = data.map(_.split(',') match { case Array(user, item, rate) =>
Rating(user.toInt, item.toInt, rate.toDouble)
})
// Build the recommendation model using ALS
val rank = 10
val numIterations = 10
val model = ALS.train(ratings, rank, numIterations, 0.01)
// Evaluate the model on rating data
val usersProducts = ratings.map { case Rating(user, product, rate) =>
(user, product)
}
val predictions =
model.predict(usersProducts).map { case Rating(user, product, rate) =>
((user, product), rate)
}
val ratesAndPreds = ratings.map { case Rating(user, product, rate) =>
((user, product), rate)
}.join(predictions)
val MSE = ratesAndPreds.map { case ((user, product), (r1, r2)) =>
val err = (r1 - r2)
err * err
}.mean()
println("Mean Squared Error = " + MSE)
// Save and load model
model.save(sc, "target/tmp/myCollaborativeFilter")
val sameModel = MatrixFactorizationModel.load(sc, "target/tmp/myCollaborativeFilter")
看官方是怎么写代码的,参照着写
开始项目Coding
步骤一: 继续在前面的项目中,新建ml包,再新建ModelTraining
package com.csylh.recommend.ml
import org.apache.spark.mllib.recommendation.{ALS, Rating}
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession
/**
* Description:
* 训练多个模型,取其中最好,即取RMSE(均方根误差)值最小的模型
*
* @Author: 留歌36
* @Date: 2019-07-17 16:56
*/
object ModelTraining {
def main(args: Array[String]): Unit = {
// 面向SparkSession编程
val spark = SparkSession.builder()
.enableHiveSupport() //开启访问Hive数据, 要将hive-site.xml等文件放入Spark的conf路径
.getOrCreate()
val sc = spark.sparkContext
// 在生产环境中一定要注意设置spark.sql.shuffle.partitions,默认是200,及需要配置分区的数量
val shuffleMinPartitions = "8"
spark.sqlContext.setConf("spark.sql.shuffle.partitions",shuffleMinPartitions)
// 训练集,总数据集的70%
val trainingData = spark.sql("select * from trainingData")
// 测试集,总数据集的30%
val testData = spark.sql("select * from testData")
//--------------------------
// 训练集,转为Rating格式
val ratingRDD = trainingData.rdd.map(x => Rating(x.getInt(0), x.getInt(1), x.getDouble(2)))
// 用于计算模型的RMSE Rating(userid, movieid, rating) ==>转为tuple (userid, movieid)
val training2 :RDD[(Int,Int)] = ratingRDD.map{ case Rating(userid, movieid, rating) => (userid, movieid)}
// 测试集,转为Rating格式
val testRDD = testData.rdd.map(x => Rating(x.getInt(0), x.getInt(1), x.getDouble(2)))
val test2 :RDD[((Int,Int),Double)]= testRDD.map {case Rating(userid, movieid, rating) => ((userid, movieid), rating)}
//--------------------------
// 特征向量的个数
val rank = 1
// 正则因子
// val lambda = List(0.001, 0.005, 0.01, 0.015)
val lambda = List(0.001, 0.005, 0.01)
// 迭代次数
val iteration = List(10, 15, 18)
var bestRMSE = Double.MaxValue
var bestIteration = 0
var bestLambda = 0.0
// persist可以根据情况设置其缓存级别
ratingRDD.persist() // 持久化放入内存,迭代中使用到的RDD都可以持久化
training2.persist()
test2.persist()
for (l <- lambda; i <- iteration) {
// 循环收敛这个模型
//lambda 用于表示过拟合的这样一个参数,值越大,越不容易过拟合,但精确度就低
val model = ALS.train(ratingRDD, rank, i, l)
//---------这里是预测-----------------
val predict = model.predict(training2).map {
// 根据 (userid, movieid) 预测出相对应的rating
case Rating(userid, movieid, rating) => ((userid, movieid), rating)
}
//-------这里是实际的predictAndFact-------------------
// 根据(userid, movieid)为key,将提供的rating与预测的rating进行比较
val predictAndFact = predict.join(test2)
// 计算RMSE(均方根误差)
val MSE = predictAndFact.map {
case ((user, product), (r1, r2)) =>
val err = r1 - r2
err * err
}.mean() // 求平均
val RMSE = math.sqrt(MSE) // 求平方根
// RMSE越小,代表模型越精确
if (RMSE < bestRMSE) {
// 将模型存储下来
model.save(sc, s"/tmp/BestModel/$RMSE")
bestRMSE = RMSE
bestIteration = i
bestLambda = l
}
println(s"Best model is located in /tmp/BestModel/$RMSE")
println(s"Best RMSE is $bestRMSE")
println(s"Best Iteration is $bestIteration")
println(s"Best Lambda is $bestLambda")
}
}
}
步骤二:将创建的项目进行打包上传到服务器
mvn clean package -Dmaven.test.skip=true
步骤三:编写shell 执行脚本
[root@hadoop001 ml]# vim model.sh
export HADOOP_CONF_DIR=/root/app/hadoop-2.6.0-cdh5.7.0/etc/hadoop
$SPARK_HOME/bin/spark-submit \
--class com.csylh.recommend.ml.ModelTraining \
--master spark://hadoop001:7077 \
--name ModelTraining \
--driver-memory 10g \
--executor-memory 5g \
/root/data/ml/movie-recommend-1.0.jar
步骤四:执行 sh model.sh 即可
sh model.sh之前:
[root@hadoop001 ~]# hadoop fs -ls /tmp
19/10/20 20:53:59 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 10 items
drwx------ - root supergroup 0 2019-04-01 16:27 /tmp/hadoop-yarn
drwx-wx-wx - root supergroup 0 2019-04-02 09:33 /tmp/hive
drwxr-xr-x - root supergroup 0 2019-10-20 19:42 /tmp/links
drwxr-xr-x - root supergroup 0 2019-10-20 19:42 /tmp/movies
drwxr-xr-x - root supergroup 0 2019-10-20 19:43 /tmp/ratings
drwxr-xr-x - root supergroup 0 2019-10-20 19:43 /tmp/tags
drwxr-xr-x - root supergroup 0 2019-10-20 20:19 /tmp/testData
drwxr-xr-x - root supergroup 0 2019-10-20 20:19 /tmp/trainingData
drwxr-xr-x - root supergroup 0 2019-10-20 20:18 /tmp/trainingDataAsc
drwxr-xr-x - root supergroup 0 2019-10-20 20:19 /tmp/trainingDataDesc
[root@hadoop001 ~]#
sh model.sh之后:
这里运行很长时间,而且很有可能出现OOM。耐心等待~~

这些点都是要关注的,再就是shuffle 很重要

等待中。。。

[root@hadoop001 ~]# hadoop fs -ls /tmp/BestModel
19/10/20 21:26:36 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 2 items
drwxr-xr-x - root supergroup 0 2019-10-20 21:00 /tmp/BestModel/0.8521581387523667
drwxr-xr-x - root supergroup 0 2019-10-20 20:56 /tmp/BestModel/0.853805599360297
[root@hadoop001 ~]#
这里得到model /tmp/BestModel/0.8521581387523667 ,感觉不是很好。资源要是多一点的话,可以把迭代次数调大一点,估计模型可以更好。这里为了演示整个流程,模型差点就差点吧。思路搞懂就好。
有任何问题,欢迎留言一起交流~~
更多文章:基于Spark的电影推荐系统:https://blog.csdn.net/liuge36/column/info/29285
基于Spark的电影推荐系统(推荐系统~4)的更多相关文章
- 基于Spark的电影推荐系统(电影网站)
第一部分-电影网站: 软件架构: SpringBoot+Mybatis+JSP 项目描述:主要实现电影网站的展现 和 用户的所有动作的地方 技术选型: 技术 名称 官网 Spring Boot 容器 ...
- 基于Spark的电影推荐系统(实战简介)
写在前面 一直不知道这个专栏该如何开始写,思来想去,还是暂时把自己对这个项目的一些想法 和大家分享 的形式来展现.有什么问题,欢迎大家一起留言讨论. 这个项目的源代码是在https://github. ...
- 基于Spark的电影推荐系统(推荐系统~2)
第四部分-推荐系统-数据ETL 本模块完成数据清洗,并将清洗后的数据load到Hive数据表里面去 前置准备: spark +hive vim $SPARK_HOME/conf/hive-site.x ...
- 基于Spark的电影推荐系统(推荐系统~7)
基于Spark的电影推荐系统(推荐系统~7) 22/100 发布文章 liuge36 第四部分-推荐系统-实时推荐 本模块基于第4节得到的模型,开始为用户做实时推荐,推荐用户最有可能喜爱的5部电影. ...
- 基于Spark的电影推荐系统(推荐系统~1)
第四部分-推荐系统-项目介绍 行业背景: 快速:Apache Spark以内存计算为核心 通用 :一站式解决各个问题,ADHOC SQL查询,流计算,数据挖掘,图计算 完整的生态圈 只要掌握Spark ...
- 基于Spark的电影推荐系统
数据文件: u.data(userid itemid rating timestamp) u.item(主要使用 movieid movietitle) 数据操作 把u.data导入RDD, t ...
- 基于Mahout的电影推荐系统
基于Mahout的电影推荐系统 1.Mahout 简介 Apache Mahout 是 Apache Software Foundation(ASF) 旗下的一个开源项目,提供一些可扩展的机器学习领域 ...
- 基于pytorch的电影推荐系统
本文介绍一个基于pytorch的电影推荐系统. 代码移植自https://github.com/chengstone/movie_recommender. 原作者用了tf1.0实现了这个基于movie ...
- 数据算法 --hadoop/spark数据处理技巧 --(9.基于内容的电影推荐 10. 使用马尔科夫模型的智能邮件营销)
九.基于内容的电影推荐 在基于内容的推荐系统中,我们得到的关于内容的信息越多,算法就会越复杂(设计的变量更多),不过推荐也会更准确,更合理. 本次基于评分,提供一个3阶段的MR解决方案来实现电影推荐. ...
随机推荐
- Core源码(五)IQueryable(转)
如果要对Iqueryable进行深入的学习,那么对于拉姆达表达式.委托需要有一定了解.这里面拉姆达表达式就是匿名函数的一种写法,而委托我们常用FUNC和ACTION,这个都是对于delegate委托的 ...
- DataGridView中实现点击单元格Cell动态添加自定义控件
场景 鼠标点击DataGridView的某个单元格时,此单元格添加一个自定义的控件,这里以 添加下拉框为例 效果 注: 博客主页: https://blog.csdn.net/badao_liuman ...
- webpack打包配置禁止html标签全部转为小写
用webpack打包页面,发现html中特别写的用来给后端识别的大写标签全部被转为了小写标签,这时候需要将加一个配置 ,caseSensitive:true ,禁止大小写转换. webpack配置: ...
- [转]Eclipse插件开发之基础篇(4) OSGi框架
原文地址:http://www.cnblogs.com/liuzhuo/archive/2010/08/18/eclipse_plugin_1_2_1.html 1. 什么是OSGi框架 OSGi(O ...
- [20190823]关于CPU成本计算3.txt
[20190823]关于CPU成本计算3.txt --//前几天探究CPU cost时遇到的问题,获取行成本时我的测试查询结果出现跳跃,不知道为什么,感觉有点奇怪,分析看看.--//ITPUB原始链接 ...
- mssql sqlserver if exists 用法大汇总
摘要: 下文讲述sqlserver中,更新脚本中常用if exists关键字的用法说明,如下所示: 实验环境:sql server 2008 R2 一.检测数据库是否存在于当前数据库引擎下 if ex ...
- tmux:终端复用神器
一.简介与安装 今天无意间从同事那里知道有 tmux 这种神器,tmux(terminal multiplexer)是Linux上的终端复用神器,可从一个屏幕上管理多个终端(准确说是伪终端).使用该工 ...
- [Go] 分页计算页码的主要逻辑
当使用imap进行读取邮件体的时候,有个函数可以根据传入的开始和结束索引来一次读取多条邮件内容主要逻辑类似这样,从1开始, 1,10 11,20 21,30 或者 1,31 32,63 ...
- Weblogic的三种部署方式
Weblogic的三种部署方式 在weblogic中部署项目通常有三种方式:第一,在控制台中安装部署:第二,将部署包放在domain域中autodeploy目录下部署:第三,使用域中配置文件c ...
- nginx 安装 lua_nginx_module 模块(nginx——lua 学习笔记1)
插入两个网站: nginx + lua 的OpenResty 开发 跟我学OpenResty(Nginx+Lua)开发目录贴 两个都是 可以根据目录一步步学习的. 1. 版本下载 nginx版本为 n ...