Spark MLlib应用

Spark MLlib应用

实验目的

深入理解和掌握Spark MLlib的操作方法;理解Spark MLlib编程解决实际问题的方法。

实验要求

  1. 掌握基于Spark MLlib的Scala编程环境配置;
  2. 掌握Spark MLlib的操作编程方法。

实验内容

  1. 参考实验四创建一个支持Spark SQL的项目
  2. 在Maven中配置Spark MLlib编程环境,pom.xml中添加:
<dependency>
	<groupId>org.apache.spark</groupId>
    <artifactId>spark-mllib_2.12</artifactId>
    <version>3.0.1</version>
</dependency>

*若安装的Spark不是3.0.1,则自己搜索适合的spark-mllib版本
3. 特征工程:基于实验四的结果进行搜索,构造用户、商品和评分数据用于协同过滤商品推荐算法
(1) 按用户ID和商品ID共同分组查询,并统计用户购买该商品的次数(不是数量)
提示:groupBy(“CustomerID”, “StockCode”).count
评分逻辑:将用户对商品的购买和重复购买行为视为对商品的评分
思考:自己设计其他的评分逻辑并实现

df.groupBy("CustomerID", "StockCode").count.show()  

在这里插入图片描述

(2) 将用户ID、商品ID和用户购买商品次数分别投影到userID、itemID和rating字段
提示:.selectExpr(“hash(CustomerID) as userID”, " hash (StockCode) as itemID", “count as rating”)
通过Spark SQL搜索生成一个DataFrame,包含userID、itemID和rating三个字段,userID和itemID均用Spark SQL Hash函数转为整型数,ALS模型不支持字符串类型输入

df.selectExpr("hash(CustomerID) as userID", " hash (StockCode) as itemID", "count as rating").show()  

在这里插入图片描述

(3) 按8:2的比例将第(2)步的结果数据划分为训练集和测试集

val Array(training, test) = df.randomSplit(Array(0.8, 0.2))

在这里插入图片描述
Training data
在这里插入图片描述

Test data

在这里插入图片描述

  1. 模型训练:训练协同过滤模型用于商品推荐
    (4) 创建一个协同过滤模型,并将用户列、商品列和评分列分别设为第(2)步中的列名,并设定其他的模型参数
    提示:
val als = new ALS()
	.setUserCol()		//设置用户字段名
	.setItemCol()		//设置商品字段名
	.setRatingCol()		//设置评分字段名
	.setMaxIter(5)			//设置最大迭代次数
.setRegParam(0.01)		//设置惩罚系数

(5) 送入训练集数据训练模型

val model = als.fit(training)

模型评估

(6) 将测试集数据送入模型进行模型评估,将均方根误差保存至本地文件
提示:model.setColdStartStrategy(“drop”) //冷启动策略设为drop以免出现nan值

val predictions = model.transform(test)
val evaluator = new RegressionEvaluator()	//创建评估器
.setMetricName("rmse")
.setLabelCol("rating")
.setPredictionCol("prediction")
val rmse = evaluator.evaluate(predictions)		//执行评估并返回均方误差
val writer = new PrintWriter(new File("……"))	//使用Scala方法保存至本地
writer.println(rmse)		//保存均方误差值
writer.close()

在这里插入图片描述

(7) 为每个用户生成三个商品推荐(DataFrame),执行搜索将推荐结果(结构体数组)使用集合函数explode展开为多行数据并持久化为JSON文件
提示:val userRecs = model.recommendForAllUsers(3)
userRecs.selectExpr(“userID”,“explode(recommendations.itemID) as itemID”)
持久化参见PPT第5章6.3节
思考:这里文件中保存的UserID和ItemID均为hash值(在3(2)步时转为了hash值),请将其保存为真实的用户ID和商品ID

userRecs.write.json("hdfs://主机名或ip地址:端口号/json文件名")

保存结果预览

在这里插入图片描述

编译和执行:

按实验二中的方法编译打包并执行程序

实验参考文献:

http://spark.apache.org/docs/latest/ml-collaborative-filtering.html

代码

package cn.edu.swpu.scs
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.ml.recommendation.ALS
import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.evaluation.RegressionEvaluator
import java.io.{PrintWriter, File}
object MLlib {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("Spark SQL").setMaster("local[*]")  
val sc = new SparkContext(conf)  
val spark = SparkSession.builder().master("local[*]").appName("Spark SQL").getOrCreate()  
val df = spark.read.json("hdfs://主机名或ip地址:端口号/json文件名")  
val df_temp = df.groupBy("CustomerID", "StockCode").count  
val df_final = df_temp.selectExpr("hash(CustomerID) as userID", " hash (StockCode) as itemID", "count as rating")  
val Array(training, test) = df_final.randomSplit(Array(0.8, 0.2))  
val als = new ALS()  
  .setUserCol("userID")     //设置用户字段名  
  .setItemCol("itemID")     //设置商品字段名  
  .setRatingCol("rating")       //设置评分字段名  
  .setMaxIter(5)            //设置最大迭代次数  
  .setRegParam(0.01)        //设置惩罚系数  
val model = als.fit(training)  
model.setColdStartStrategy("drop")  //冷启动策略设为drop以免出现nan值  
val predictions = model.transform(test)  
val evaluator = new RegressionEvaluator()   //创建评估器  
  .setMetricName("rmse")  
  .setLabelCol("rating")  
  .setPredictionCol("prediction")  
val rmse = evaluator.evaluate(predictions)      //执行评估并返回均方误差  
val writer = new PrintWriter(new File("本地文件名"))  //使用Scala方法保存至本地  
writer.println(rmse)        //保存均方误差值  
writer.close()  
val userRecs = model.recommendForAllUsers(3)  
userRecs.selectExpr("userID","explode(recommendations.itemID) as itemID")  
userRecs.write.json("hdfs://主机名或ip地址:端口号/json文件名")  
}
}

实验感悟

唯一遇到的问题就是创建als变量的时候,有点问题。
之前是这样导入的包
import org.apache.spark.mllib.evaluation.RegressionEvaluator
后将mllib改为ml就好了
import org.apache.spark.ml.evaluation.RegressionEvaluator

Spark中ml和mllib的主要区别和联系如下:
ml和mllib都是Spark中的机器学习库,目前常用的机器学习功能2个库都能满足需求。
spark官方推荐使用ml, 因为ml功能更全面更灵活,未来会主要支持ml,mllib很有可能会被废弃(据说可能是在spark3.0中deprecated)。
ml主要操作的是DataFrame, 而mllib操作的是RDD,也就是说二者面向的数据集不一样。相比于mllib在RDD提供的基础操作,ml在DataFrame上的抽象级别更高,数据和操作耦合度更低。
DataFrame和RDD什么关系?DataFrame是Dataset的子集,就是Dataset[Row], 而DataSet是对RDD的封装,对SQL之类的操作做了很多优化。
相比于mllib在RDD提供的基础操作,ml在DataFrame上的抽象级别更高,数据和操作耦合度更低。
ml中的操作可以使用pipeline, 跟sklearn一样,可以把很多操作(算法/特征提取/特征转换)以管道的形式串起来,然后让数据在这个管道中流动。大家可以脑补一下Linux管道在做任务组合时有多么方便。
ml中无论是什么模型,都提供了统一的算法操作接口,比如模型训练都是fit;不像mllib中不同模型会有各种各样的trainXXX。
mllib在spark2.0之后进入维护状态, 这个状态通常只修复BUG不增加新功能。

我认为可能就是ml主要操作是DataFrame的原因

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值